You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中try-except嵌套失效问题排查(CS50P作业)

CS50P "Outdated" 题目调试问题

我在完成CS50P的"Outdated"第4题时,尝试用try-except替代if/else处理日期输入,但代码里嵌套的第二个except总是触发,导致第二部分处理月份名称的逻辑无法生效。如果把msg.split(" ")的逻辑放到前面,这部分能正常工作,但原来处理斜杠分隔日期的代码又失效了。现在只有第一部分代码能执行,终端没有报错信息,希望找出问题所在。

months = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
]

while True:
    msg = input("Date: ")
    try:
        msg = msg.split("/")
        msg[0] = int(msg[0])
        msg[1] = int(msg[1])
        msg[2] = int(msg[2])
        if 0 < msg[0] < 13 and 0 < msg[1] < 32 and 0 < msg[2]:
            MM = f"{msg[0]:02}"
            DD = f"{msg[1]:02}"
            YY = f"{msg[2]:02}"
            break
    except:
        try:
            msg = msg.split(" ")
            msg[0] = int(months.index(msg[0])+1)
            msg[1] = msg[1].replace(",",""
            msg[1] = int(msg[1])
            msg[2] = int(msg[2])
            if 0 < msg[0] < 13 and 0 < msg[1] < 32 and 0 < msg[2]:
                MM = f"{msg[0]:02}"
                DD = f"{msg[1]:02}"
                YY = f"{msg[2]:02}"
                break
        except:
            print()
            pass

print(YY,MM,DD, sep="-")

问题分析

  1. 变量被意外修改:第一个try块中,你把原始输入字符串msg重新赋值为msg.split("/")的结果(一个列表)。当输入是月份名称格式(比如"January 1, 2020"),第一个try执行失败进入except后,此时msg已经是列表而非原始字符串,调用msg.split(" ")会触发AttributeError(列表没有split方法),直接进入第二个except,导致月份名称处理逻辑无法执行。

  2. 语法错误:msg[1] = msg[1].replace(",",""缺少了闭合的引号,正确写法应为msg[1].replace(",", ""),这个语法错误会直接导致代码逻辑中断。

  3. 裸except的隐患:使用无限制的except会捕获所有异常(包括语法错误、属性错误等),难以定位具体问题,应该捕获特定异常类型(如ValueError、IndexError)。

修正后的代码

months = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
]

while True:
    msg = input("Date: ")
    # 处理斜杠分隔的日期格式(MM/DD/YYYY)
    try:
        parts = msg.split("/")
        month = int(parts[0])
        day = int(parts[1])
        year = int(parts[2])
        if 1 <= month <= 12 and 1 <= day <= 31 and year > 0:
            MM = f"{month:02}"
            DD = f"{day:02}"
            YY = f"{year:02}" if year < 100 else str(year)
            break
    except (ValueError, IndexError):
        # 处理月份名称格式(Month Day, Year)
        try:
            parts = msg.split(" ")
            # 检查是否有足够的部分,且日期部分包含逗号
            if len(parts) != 3 or "," not in parts[1]:
                raise ValueError("Invalid format")
            month_name = parts[0].strip()
            day = int(parts[1].replace(",", ""))
            year = int(parts[2])
            if month_name not in months:
                raise ValueError("Invalid month name")
            month = months.index(month_name) + 1
            if 1 <= day <= 31 and year > 0:
                MM = f"{month:02}"
                DD = f"{day:02}"
                YY = f"{year:02}" if year < 100 else str(year)
                break
        except (ValueError, IndexError):
            print()
            continue

print(f"{YY}-{MM}-{DD}")

修正要点

  • 用临时变量parts替代直接修改原始输入msg,确保两个分支都能访问到原始输入字符串。
  • 修复了replace方法的语法错误。
  • 改为捕获特定异常类型,避免误捕获无关错误。
  • 增加了格式合法性检查(比如月份名称是否在列表中、日期部分是否有逗号),逻辑更严谨。

内容的提问来源于stack exchange,提问作者Angel Trejo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 00:45:30