class 定义中未绑定的局部变量在全局命名空间中查找 - 这是什么意思?
Unbound local variables in a class definition are looked up in the global namespace - what does it mean?
https://docs.python.org/3/reference/executionmodel.html#resolution-of-names的最后一段说
Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace.
引用文字的最后一句是什么意思?一开始我从中推断出下面的代码会打印1
a = 1
def foo():
a = 2
def bar():
class Bar:
b = a
print(Bar.b)
bar()
foo()
但我错了 - 由上面的代码组成的模块,当 运行 时,打印 2
,即 class 定义中的名称 a
,甚至虽然它没有绑定在 class 定义块中,也没有绑定在它外面的本地块中,但没有在全局命名空间中查找,这与文档所说的相反。
我尝试了下面描述的另一个代码片段(使用 del
语句,这是一个绑定其中变量的构造)
a = 1
def foo():
a = 2
def bar():
class Bar:
del a
print(Bar.b)
bar()
foo()
但是 del
语句引发了 NameError: name 'a' is not defined
.
所以,我不明白,那句话是什么意思?
if a name is bound in a block, it is a local variable of that block, unless declared as nonlocal or global.
在您的第一个代码块中,a
未绑定到您的 class Bar
定义中的任何内容,因此它不是该代码块的局部变量。
绑定名称的一种方法是在赋值语句的 left-hand 端使用它。这是一个例子。
a = 1
def foo():
a = 2
class Bar:
b = a
a = 3
print(Bar.b)
foo()
结果:
1
这演示了"unbound local variables are looked up in the global namespace"的原理——b = a
使用全局a
的值而不是[=19=局部的a
的值].
在您的第二个示例中,a
被认为是 class Bar
块的本地,因为 "A target occurring in a del statement is also considered bound" 用于确定名称的范围。但是 "unbound local variables are looked up in the global namespace" 不相关,因为 del
不需要查找名称的值来解除绑定。
为了更好地衡量,我们可以通过实验确认 del
语句向解释器发出信号,表明名称应被视为本地名称。
a = 1
def foo():
a = 2
class Bar:
print(a)
del a
foo()
结果:
1
Traceback (most recent call last):
File "C:\Users\Kevin\Desktop\test.py", line 7, in <module>
foo()
File "C:\Users\Kevin\Desktop\test.py", line 4, in foo
class Bar:
File "C:\Users\Kevin\Desktop\test.py", line 6, in Bar
del a
NameError: name 'a' is not defined
这里我们看到print(a)
成功的查到了局部变量a
的值,然后在下一行就崩溃了,因为del
不能删除一个unbound local变量。
我觉得可以补一下
Python pre-computes which frame contains each name before executing the body of the function.
意思是这样的现象:
In [1]: a = 1
In [2]: def test():
...: print(a)
...:
In [3]: test()
1
In [4]: def test():
...: print(a)
...: a = 1
...:
In [5]: test()
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-5-fbd55f77ab7c> in <module>
----> 1 test()
<ipython-input-4-a08051373573> in test()
1 def test():
----> 2 print(a)
3 a = 1
4
UnboundLocalError: local variable 'a' referenced before assignment
In [6]:
错误local variable 'a' referenced before assignment
表示Pythonpre-computes那个函数test
frame有一个名为a
的局部变量,我们必须先将一个对象赋值给a
以后再参考。
作用域的局部变量是在该作用域中任何地方定义的任何名称。值得注意的是,变量本身是局部的,而不是分配给它的值 - 局部变量可以在赋值之前存在或与赋值无关。
>>> def foo(): # new function scope
... a = 3 # local variable `a`
... b: int # local variable `b`
... c = 3 # local variable `c`
... del c
... print(x)
... x = 3 # local variable `x`
... foo()
UnboundLocalError: local variable 'x' referenced before assignment
未绑定局部变量就是这样一个没有值绑定到它的局部变量。在上面的示例中,所有 b
、c
和 x
在某些时候都是未绑定的。
您的示例 都没有访问未绑定的局部变量。两者都查找名称 a
,但从未分配给它。
在功能块中,引用未绑定的局部变量是错误的,即UnboundLocalError
。该名称是否也存在于封闭范围内并不重要。
>>> x = 1
>>> def foo():
... b = x # local variable is looked up locally
... x = 2 # make `x` a local variable
... foo()
UnboundLocalError: local variable 'x' referenced before assignment
在 class 块 中,引用未绑定的局部变量回退到全局范围内的查找。这可能成功也可能不成功。
>>> x = 1
>>> class Foo:
... b = x # local variable is looked up locally *or globally*
... x = 2 # make `x` a local variable
... print(Foo.b, Foo.x)
1 2
>>> class Foo:
... b = y # local variable is looked up locally *or globally*
... y = 2 # make `y` a local variable
... print(Foo.b, Foo.y)
NameError: name 'y' is not defined
https://docs.python.org/3/reference/executionmodel.html#resolution-of-names的最后一段说
Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace.
引用文字的最后一句是什么意思?一开始我从中推断出下面的代码会打印1
a = 1
def foo():
a = 2
def bar():
class Bar:
b = a
print(Bar.b)
bar()
foo()
但我错了 - 由上面的代码组成的模块,当 运行 时,打印 2
,即 class 定义中的名称 a
,甚至虽然它没有绑定在 class 定义块中,也没有绑定在它外面的本地块中,但没有在全局命名空间中查找,这与文档所说的相反。
我尝试了下面描述的另一个代码片段(使用 del
语句,这是一个绑定其中变量的构造)
a = 1
def foo():
a = 2
def bar():
class Bar:
del a
print(Bar.b)
bar()
foo()
但是 del
语句引发了 NameError: name 'a' is not defined
.
所以,我不明白,那句话是什么意思?
if a name is bound in a block, it is a local variable of that block, unless declared as nonlocal or global.
在您的第一个代码块中,a
未绑定到您的 class Bar
定义中的任何内容,因此它不是该代码块的局部变量。
绑定名称的一种方法是在赋值语句的 left-hand 端使用它。这是一个例子。
a = 1
def foo():
a = 2
class Bar:
b = a
a = 3
print(Bar.b)
foo()
结果:
1
这演示了"unbound local variables are looked up in the global namespace"的原理——b = a
使用全局a
的值而不是[=19=局部的a
的值].
在您的第二个示例中,a
被认为是 class Bar
块的本地,因为 "A target occurring in a del statement is also considered bound" 用于确定名称的范围。但是 "unbound local variables are looked up in the global namespace" 不相关,因为 del
不需要查找名称的值来解除绑定。
为了更好地衡量,我们可以通过实验确认 del
语句向解释器发出信号,表明名称应被视为本地名称。
a = 1
def foo():
a = 2
class Bar:
print(a)
del a
foo()
结果:
1
Traceback (most recent call last):
File "C:\Users\Kevin\Desktop\test.py", line 7, in <module>
foo()
File "C:\Users\Kevin\Desktop\test.py", line 4, in foo
class Bar:
File "C:\Users\Kevin\Desktop\test.py", line 6, in Bar
del a
NameError: name 'a' is not defined
这里我们看到print(a)
成功的查到了局部变量a
的值,然后在下一行就崩溃了,因为del
不能删除一个unbound local变量。
我觉得可以补一下
Python pre-computes which frame contains each name before executing the body of the function.
意思是这样的现象:
In [1]: a = 1
In [2]: def test():
...: print(a)
...:
In [3]: test()
1
In [4]: def test():
...: print(a)
...: a = 1
...:
In [5]: test()
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-5-fbd55f77ab7c> in <module>
----> 1 test()
<ipython-input-4-a08051373573> in test()
1 def test():
----> 2 print(a)
3 a = 1
4
UnboundLocalError: local variable 'a' referenced before assignment
In [6]:
错误local variable 'a' referenced before assignment
表示Pythonpre-computes那个函数test
frame有一个名为a
的局部变量,我们必须先将一个对象赋值给a
以后再参考。
作用域的局部变量是在该作用域中任何地方定义的任何名称。值得注意的是,变量本身是局部的,而不是分配给它的值 - 局部变量可以在赋值之前存在或与赋值无关。
>>> def foo(): # new function scope
... a = 3 # local variable `a`
... b: int # local variable `b`
... c = 3 # local variable `c`
... del c
... print(x)
... x = 3 # local variable `x`
... foo()
UnboundLocalError: local variable 'x' referenced before assignment
未绑定局部变量就是这样一个没有值绑定到它的局部变量。在上面的示例中,所有 b
、c
和 x
在某些时候都是未绑定的。
您的示例 都没有访问未绑定的局部变量。两者都查找名称 a
,但从未分配给它。
在功能块中,引用未绑定的局部变量是错误的,即UnboundLocalError
。该名称是否也存在于封闭范围内并不重要。
>>> x = 1
>>> def foo():
... b = x # local variable is looked up locally
... x = 2 # make `x` a local variable
... foo()
UnboundLocalError: local variable 'x' referenced before assignment
在 class 块 中,引用未绑定的局部变量回退到全局范围内的查找。这可能成功也可能不成功。
>>> x = 1
>>> class Foo:
... b = x # local variable is looked up locally *or globally*
... x = 2 # make `x` a local variable
... print(Foo.b, Foo.x)
1 2
>>> class Foo:
... b = y # local variable is looked up locally *or globally*
... y = 2 # make `y` a local variable
... print(Foo.b, Foo.y)
NameError: name 'y' is not defined