python - Python 的闭包是如何工作的
问题描述
我试图了解闭包在 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 的变量提升的东西?
解决方案
在这两个示例中,您都在start变量中接收到闭包方法返回的值,即方法闭包被执行并返回内部本地方法。所以count变量也被定义并初始化为值 0
当您使用start()调用内部方法时,该方法将被执行,到那时,在这两种情况下,count 变量都已经存在
但是如果你有这样的代码,那么就会有一个参考错误
def closure():
def inner():
nonlocal count
count += 1
print(count)
inner()
count = 0
start = closure()
这里在定义计数之前调用内部方法
推荐阅读
- javascript - JavaScript 中 let 和 const 的变量声明在块作用域和全局作用域中的工作方式不同吗?
- azure - 如何在 Micorsoft Azure / Microsoft Synapse 无服务器 SQL 池服务中实现外部表的行级安全功能?
- neo4j - ClientError 404,无法将 mongodb 连接到 neo4j
- javascript - 带有千位分隔符的动画数字
- networking - 使用来自其他项目的 NEG 作为 Google Cloud Load Balancer 后端
- python - 为所有 pandas 数据框列名添加一个数字,但列名由字符串和整数组成
- excel - Alteryx 中一个 Excel 工作簿中的数据
- python - 如何在 Flask 中共享在上下文之外创建的会话值?
- javascript - 第三个查询可以在同一个 db.any() 调用中的两个查询中间执行吗?
- python - 在组百分位下过滤数据框中的行