我试图理解闭包在Python中是如何工作的,我发现了以下代码片段:
def closure():
count = 0
def inner():
nonlocal count
count += 1
print(count)
return inner
start = closure()
start() # prints 1
start() # prints 2
start() # prints 3
我可以理解这段代码,因为当inner
函数被定义时,封闭作用域有一个名为count的变量,值为0,内部函数将remember
这个值
但是,如果我将count = 0
移到内部函数下面,那么代码会变成:
def closure():
def inner():
nonlocal count
count += 1
print(count)
count = 0
return inner
start = closure()
start() # prints 1
start() # prints 2
start() # prints 3
令我惊讶的是,代码仍然可以很好地工作,这让我很困惑。当inner
被定义时,变量count
不存在于封闭作用域中,那么inner
函数怎么能够记住此时命名空间中还不存在的值呢?你知道吗
是不是因为Python中也存在类似于JS的变量hoisting的东西?你知道吗
从Resolution of Names:
(我的)
赋值是name binding operations,因此只要
count = 0
存在于函数中的任何地方,count
被认为是该函数的局部变量,inner
将引用该变量。(不过,如果在将值赋给count
之前调用inner()
,则会得到一个异常。)在这两个示例中,您都收到start变量中closure方法返回的值,即执行closure方法并返回内部局部方法。因此count变量也被定义并用值0初始化
当您使用start()调用inner方法时,该方法将被执行,此时,在这两种情况下,count变量已经存在
但是如果你有这样的代码,那么就会有一个引用错误
这里,在定义计数之前调用内部方法
相关问题 更多 >
编程相关推荐