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

Python中match语句内变量的存储位置及跨case访问问题

问题解答

1. todos变量的存储位置

Python没有块级作用域(像if、for、match这类代码块不会创建独立的作用域),你在case 'add'分支里定义的todos,属于全局作用域(因为这段代码没有包裹在函数或类中,直接在模块级别执行)。一旦case 'add'的代码执行过,这个变量就会被存在全局命名空间里,直到程序结束。

2. 不同case分支能访问该变量的原因

所有match的case分支都共享同一个外层作用域(这里就是全局作用域),只要todos变量已经被定义过(也就是case 'add'的代码执行过),后续的show、edit、complete分支就能直接访问到这个变量——因为它们不在独立的作用域里,能直接读取外层作用域的变量。

为什么首次执行show会报错?

当你第一次直接选show时,case 'add'的代码从来没运行过,todos变量根本没被定义过,Python在当前作用域里找不到这个变量,就会抛出NameError: name 'todos' is not defined。而先执行add分支的话,todos已经被创建并赋值了,后续分支自然能正常访问。

修复建议

要避免首次执行show/edit/complete分支报错,最好在程序开头就初始化todos变量,不管有没有执行add操作,先从文件读取(文件不存在就初始化为空列表):

# 初始化todos变量,提前处理文件不存在的情况
try:
    with open('todos.txt', 'r') as file:
        todos = file.readlines()
except FileNotFoundError:
    todos = []

while True:
    user_action = input("Type add, show, edit, complete or exit: ").strip().lower()

    match user_action:
        case 'add':
            todo = input("Enter a todo: ") + "\n"
            todos.append(todo)
            with open('todos.txt', 'w') as file:
                file.writelines(todos)
        case 'show' | 'display':
            for index, item in enumerate(todos):
                # 去掉换行符避免重复换行
                print(f"{index+1}-{item.strip()}")
        case 'edit':
            try:
                number = int(input("Number of the todo to edit: ")) - 1
                new_todo = input("Enter new todo: ").capitalize() + "\n"
                todos[number] = new_todo
                with open('todos.txt', 'w') as file:
                    file.writelines(todos)
            except (ValueError, IndexError):
                print("Invalid todo number!")
        case 'complete':
            try:
                number = int(input("Number of the todo to complete: ")) - 1
                todos.pop(number)
                with open('todos.txt', 'w') as file:
                    file.writelines(todos)
            except (ValueError, IndexError):
                print("Invalid todo number!")
        case 'exit':
            break
        case _:
            print("Hey, you entered an unknown command")
print("Bye!")

(顺便优化了文件操作,用with语句自动关闭文件,还加了异常处理避免输入非数字或无效索引的报错)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:40:44