使用 UnboundLocalError 的本地和全局引用
Local and global references with UnboundLocalError
我不太明白为什么代码
def f():
print(s)
s = "foo"
f()
运行得很好但是
def f():
print(s)
s = "bar"
s = "foo"
f()
给我 UnboundLocalError。我知道我可以通过将 s 声明为函数内部的全局变量或简单地将 s 参数传递给函数来解决此问题。
我还是不明白python怎么知道在该行执行之前函数内部是否引用了s?当函数被读入全局框架时,python 是否生成某种所有局部变量引用的列表?
是的,Python 将超前恢复在本地范围内声明的所有变量。这些将掩盖全局变量。
所以在你的代码中:
def f():
print(s)
s = "foo"
f()
Python 在本地范围内没有找到 s
,因此它尝试从全局范围恢复它并找到 "foo"
.
现在在另一种情况下会发生以下情况:
def f():
print(s)
s = "bar
s = "foo"
f()
Python 知道 s
是一个局部变量,因为它在运行前进行了前瞻,但在运行时它还没有被赋值,所以它引发了异常。
请注意 Python 甚至可以让您引用尚未在任何地方声明的变量。如果你这样做:
def foo():
return x
f()
你会得到一个NameError
,因为Python,当找不到时,x
作为局部变量只会记住,在运行时它应该寻找一个名为x
如果不存在则失败。
所以UnboundLocalError
意味着变量可能最终在范围内被声明但还没有被声明。另一方面 NameError
意味着该变量永远不会在局部范围内声明,因此 Python 试图在全局范围内找到它,但它不存在。
其他答案都集中在这方面的实际方面,但没有真正回答你问的问题。
是的,Python 编译器会在编译代码块(例如在 def
中)时跟踪分配了哪些变量。如果在块中分配了一个名称,编译器将其标记为 local.Take 查看 function.__code__.co_varnames
以查看编译器已识别哪些变量。
nonlocal
和 global
语句可以覆盖它。
我不太明白为什么代码
def f():
print(s)
s = "foo"
f()
运行得很好但是
def f():
print(s)
s = "bar"
s = "foo"
f()
给我 UnboundLocalError。我知道我可以通过将 s 声明为函数内部的全局变量或简单地将 s 参数传递给函数来解决此问题。
我还是不明白python怎么知道在该行执行之前函数内部是否引用了s?当函数被读入全局框架时,python 是否生成某种所有局部变量引用的列表?
是的,Python 将超前恢复在本地范围内声明的所有变量。这些将掩盖全局变量。
所以在你的代码中:
def f():
print(s)
s = "foo"
f()
Python 在本地范围内没有找到 s
,因此它尝试从全局范围恢复它并找到 "foo"
.
现在在另一种情况下会发生以下情况:
def f():
print(s)
s = "bar
s = "foo"
f()
Python 知道 s
是一个局部变量,因为它在运行前进行了前瞻,但在运行时它还没有被赋值,所以它引发了异常。
请注意 Python 甚至可以让您引用尚未在任何地方声明的变量。如果你这样做:
def foo():
return x
f()
你会得到一个NameError
,因为Python,当找不到时,x
作为局部变量只会记住,在运行时它应该寻找一个名为x
如果不存在则失败。
所以UnboundLocalError
意味着变量可能最终在范围内被声明但还没有被声明。另一方面 NameError
意味着该变量永远不会在局部范围内声明,因此 Python 试图在全局范围内找到它,但它不存在。
其他答案都集中在这方面的实际方面,但没有真正回答你问的问题。
是的,Python 编译器会在编译代码块(例如在 def
中)时跟踪分配了哪些变量。如果在块中分配了一个名称,编译器将其标记为 local.Take 查看 function.__code__.co_varnames
以查看编译器已识别哪些变量。
nonlocal
和 global
语句可以覆盖它。