Python如何识别函数中的全局变量与局部变量?为何未执行赋值前就判定变量为局部?
为什么函数内未执行赋值就触发UnboundLocalError?
你的猜测完全正确!Python对变量作用域的判定不是在运行时逐行执行的时候做的,而是在函数定义的编译阶段就完成了。
具体来说,当Python解析一个函数的代码时,会从头到尾扫描整个函数体:
- 如果发现函数内部有对某个变量的赋值操作(比如你的
foo3里的s = 'bbb'),不管这个赋值语句在函数的哪个位置,Python都会直接把这个变量标记为该函数的局部变量。 - 反之,如果函数内部没有对变量的赋值操作,Python才会在运行时去外层作用域(比如全局作用域)查找这个变量。
回到你的foo3例子:
s = 5 def foo3(): print(s) # 这里Python已经认定s是局部变量,但此时还未赋值 s = 'bbb' print(s)
当Python解析foo3的定义时,看到了后面的s = 'bbb',就立刻把s标记为foo3的局部变量。等到运行foo3()时,执行第一个print(s)的时候,局部变量s还没有被赋值(赋值语句在后面),所以就抛出了UnboundLocalError——相当于你在使用一个还没定义的局部变量。
对比一下你的其他例子:
foo1里没有对s的赋值,所以Python会去全局作用域找s,运行正常。foo2用了global s,明确告诉Python这个s是全局变量,所以赋值操作会直接修改全局的s,也不会报错。
总结一下:Python的作用域规则是"先静态标记,再动态查找"——函数定义时就确定了哪些变量是局部的,运行时就按照这个标记来查找变量,而不是逐行判断。
内容的提问来源于stack exchange,提问作者Mr.O
相关产品推荐
相关产品推荐

