[英]Python closures
def counter(x):
def _cnt():
#nonlocal x
x = x+1
print(x)
return x
return _cnt
a = counter(0)
print(a())
Above code gives the following error 上面的代码给出了以下错误
UnboundLocalError: local variable 'x' referenced before assignment UnboundLocalError:赋值前引用的局部变量'x'
Why this is not able to create a new object with value 'x+1' in the namespace of _cnt and bind it to x. 为什么这不能在_cnt的命名空间中创建值为'x + 1'的新对象并将其绑定到x。 we will have reference x in both function namespaces
我们将在两个函数名称空间中引用x
As soon as you assign to a name in a given scope, all references to the same name inside the same scope are local. 只要分配给定范围内的名称,同一范围内对同一名称的所有引用都是本地的。 Hence
x + 1
cannot be evaluated (as it tries to reference the local x
). 因此,无法评估
x + 1
(因为它试图引用本地x
)。
Hence this works: 因此这有效:
def f():
x = 42
def g():
print(x)
g()
f()
But this doesn't: 但这不是:
def f():
x = 42
def g():
print(x)
x = 42
g()
f()
The first print
has this bytecode: 第一个
print
有这个字节码:
0 LOAD_GLOBAL 0 (print)
3 LOAD_DEREF 0 (x)
6 CALL_FUNCTION 1
9 POP_TOP
while the second print
has this one: 而第二个
print
有这个:
0 LOAD_GLOBAL 0 (print)
3 LOAD_FAST 0 (x)
6 CALL_FUNCTION 1
9 POP_TOP
The scopes of function counter
and _cnt
are not the same. 函数
counter
和_cnt
的范围不一样。 Even though they're nested, it doesn't matter. 即使它们是嵌套的,也没关系。
So the x
in counter
does not exist in _cnt
. 所以
_cnt
中不存在counter
中的x
。 Perhaps pass it as an argument (or use nonlocal
, as you seemed to have understood) 也许把它作为一个论点传递(或者使用
nonlocal
,正如你似乎已经理解的那样)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.