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

Python开发工具程序时if嵌套try-except触发变量未定义NameError

NameError报错的核心诱因
  • 缩进逻辑完全错位,try-except的代码边界搭建错误
    原代码将整套计算器运算的判断逻辑,全部写在了except IndexError块内部。正常运行时,只有try块抛出指定异常才会执行except内的代码;如果try块执行顺利,这些运算逻辑根本不会触发。
  • 异常触发路径下变量从未完成赋值
    只要用户输入的计算器操作选项超出范围(比如输入0、输入5),try块执行到small_list[small_option]时就会直接抛出IndexError,程序立刻跳转到except分支,此时try块里给user_option赋值的代码段根本没执行完,自然找不到这个变量,触发NameError。
  • 选项映射逻辑完全错位
    原代码设计里用户输入1对应加法,但实际是把small_option作为索引去取列表值,比如用户输入1,得到的user_option是1,和后续判断user_option == 0触发加法的逻辑完全不匹配,就算没有报错,运算分支也会走歪。
  • 业务分支完全串台
    原代码把日历工具、随机数生成器的逻辑,全部硬塞在计算器的判断分支内部,不管用户选哪个大类工具,流程都会走进计算器的代码段,和最初的三功能设计完全不符。
  • 异常捕获范围缺失
    原代码只捕获IndexError,但输入转int时会抛ValueError、除法运算时可能抛ZeroDivisionError,这些错误都没有被兜住,程序随时可能直接崩溃。
可落地的修正方案
  • 重新梳理代码缩进层级,按功能做严格分层:大类工具选择后,根据用户输入的0/1/2值,分别进入计算器、日历、随机数的独立分支,杜绝跨功能的代码混放
  • 把try-except的作用范围限定在输入校验环节,except块只负责打印错误提示、通过continue让程序回到主流程重新等待输入,禁止把正常业务逻辑写在except块里
  • 去掉无意义的列表索引映射,直接用用户输入的选项值做分支判断,避免索引错位
  • 扩大异常捕获范围,覆盖输入转换、运算过程中所有可能出现的常见错误
  • 补充函数返回值的打印逻辑:原代码调用calendar.month()、random.randint()后没有把结果输出给用户,相当于无效调用
修正后的可运行参考代码
import calendar
import random


def adding(para1, para2):
    return para1 + para2


def substract(para1, para2):
    return para1 - para2


def multiplying(para1, para2):
    return para1 * para2


def dividing(para1, para2):
    return para1 / para2


while True:
    try:
        big_option = input("Which tool will you use? \n 0. Calculator \n 1. Calendar \n 2. Random number generator\n")
        big_option_int = int(big_option)
        # 大类选项范围校验
        if big_option_int not in [0, 1, 2]:
            print("Invalid option, please select 0/1/2")
            continue

        # 分支0:计算器功能
        if big_option_int == 0:
            small_option = int(input("Which operation do you want to do? \n 1. Adding \n 2. Subtracting \n 3. Multiplying \n 4. Dividing\n"))
            # 运算选项范围校验
            if small_option not in [1, 2, 3, 4]:
                print("Invalid option, please select 1-4")
                continue
            num1 = float(input("Enter first number: "))
            num2 = float(input("Enter second number: "))
            # 执行对应运算并输出
            if small_option == 1:
                print(f"The sum is {num1} + {num2} = {adding(num1, num2)}")
            elif small_option == 2:
                print(f"The subtraction is {num1} - {num2} = {substract(num1, num2)}")
            elif small_option == 3:
                print(f"The multiplying is {num1} * {num2} = {multiplying(num1, num2)}")
            elif small_option == 4:
                print(f"The divide is {num1} / {num2} = {dividing(num1, num2)}")

        # 分支1:日历功能
        elif big_option_int == 1:
            user_year = int(input("Please input the year you want to get: "))
            user_month = int(input("Please input the month you want to get: "))
            # 打印日历结果
            print(calendar.month(user_year, user_month))

        # 分支2:随机数生成功能
        elif big_option_int == 2:
            random_min = int(input("Please input the lower bound number: "))
            random_max = int(input("Please input the upper bound number: "))
            # 打印生成的随机数
            print(f"Generated random number: {random.randint(random_min, random_max)}")

    except ValueError:
        print("Invalid input, please enter a valid number")
    except ZeroDivisionError:
        print("Error: Cannot divide by zero")

内容的提问来源于stack exchange,提问作者Susie Xue

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 08:36:03