Python命名空间学习遇错:变量spam被引用前未声明
为什么我的Python命名空间代码报错"variable referenced before assignment"?
嘿,我来帮你把这个问题掰扯明白~
首先,咱们先抓准报错的核心原因:你在scope_test()函数里第一次执行print("before local assignment:", spam)的时候,当前scope_test()的函数作用域里根本还没定义spam变量!
你可能以为do_local()里定义了spam就能在外层用,但其实:
do_local()里的spam = "local spam"是创建了一个仅属于do_local()自身的局部变量,它的作用范围只限于这个小函数内部,出了do_local()就彻底消失了,完全不会影响外层scope_test()作用域里的变量。
那怎么改呢?我们需要先在scope_test()的作用域里初始化spam变量,给后续操作打个基础。另外我再帮你理清楚nonlocal和global的实际效果,修改后的代码如下:
def scope_test(): # 先在scope_test的作用域里初始化spam,解决未声明的问题 spam = "initial spam" def do_local(): spam = "local spam" # 仅在do_local内部生效的局部变量 def do_nonlocal(): nonlocal spam # 指向外层嵌套作用域(scope_test)的spam spam = "nonlocal spam" def do_global(): global spam # 指向全局作用域的spam spam = "global spam" print("初始值:", spam) do_local() print("调用do_local后(不影响外层):", spam) do_nonlocal() print("调用do_nonlocal后(修改外层):", spam) spam = "test spam" print("手动赋值后:", spam) do_global() print("调用do_global后(修改全局,不影响当前函数作用域):", spam) scope_test() # 打印全局作用域的spam,验证global的效果 print("全局作用域的spam:", spam)
运行这段代码的输出会是:
初始值: initial spam 调用do_local后(不影响外层): initial spam 调用do_nonlocal后(修改外层): nonlocal spam 手动赋值后: test spam 调用do_global后(修改全局,不影响当前函数作用域): test spam 全局作用域的spam: global spam
最后再给你梳理下几个赋值逻辑的区别:
- 普通赋值(比如
do_local()里的操作):创建当前函数的局部变量,和外层变量完全无关 nonlocal:修改紧邻的外层嵌套函数作用域里的变量(不能用来修改全局变量)global:修改全局作用域里的变量,和当前函数作用域的变量相互独立
内容的提问来源于stack exchange,提问作者Mahesh
相关产品推荐
相关产品推荐

