a = 10
def f():
print(1)
print(a) # UnboundLocalError raised here
a = 20
f()
这段代码当然会引发 UnboundLocalError: local variable 'a' referenced before assignment
。但是为什么会在 print(a)
行引发此异常?
如果解释器逐行执行代码(就像我想的那样),当到达 print(a)
时它不会知道有什么错误;它只会认为 a
引用了全局变量。
所以解释器似乎提前读取了整个函数,以确定是否使用 a
进行赋值。这在任何地方都有记录吗?有没有其他解释器向前看的情况(除了检查语法错误)?
澄清一下,异常本身是非常清楚的:全局变量可以在没有 global
声明的情况下读取,但不能写入(这种设计可以防止由于无意中修改全局变量而导致的错误;这些错误特别难以解决调试,因为它们会导致错误发生在远离错误代码位置的地方)。我只是好奇为什么提早提出异常。
最佳答案
根据 Python's documentation ,解释器将首先注意到在 f()
范围内对名为 a
的变量的赋值(无论赋值在函数中的位置如何),然后作为 a结果仅将变量 a
识别为该范围内的局部变量。此行为有效 shadows全局变量a
。
异常随后“提早”引发,因为“逐行”执行代码的解释器将遇到引用局部变量的打印语句,此时该变量尚未绑定(bind)(记住,Python 正在寻找一个 local
变量)。
正如您在问题中提到的,必须使用 global
关键字明确告诉编译器此范围内的赋值是对全局变量完成的,正确的代码是:
a = 10
def f():
global a
print(1)
print(a) # Prints 10 as expected
a = 20
f()
作为@2rs2ts在现已删除的答案中说,这很容易解释为“Python 不仅仅是被解释,它被编译成字节码,而不仅仅是逐行解释”。
关于python - 为什么对全局变量的错误分配会提早引发异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40822067/