闭包坑点
上篇参考:Python 闭包使用注意点,接下来,介绍使用闭包,经常会犯的一个错误:演示代码如下,
In [6]: def boy(pos): ...: def run(step): ...: pos = pos + step ...: return pos ...: return run ...:
In [7]: r = boy(0)
In [9]: r(10) ---------------------------------------------------------------------------UnboundLocalError Traceback (most recent call last)<ipython-input-9-5a4ba556b403> in <module>----> 1 r(10)
<ipython-input-6-9b6d05d20cb3> in run(step) 1 def boy(pos): 2 def run(step):----> 3 pos = pos + step 4 return pos 5 return run
UnboundLocalError: local variable 'pos' referenced before assignment
分析原因
python 规则指定所有在赋值语句左面的变量都是局部变量,则在闭包 run() 中,变量 pos 在赋值符号"="的左面,被 python 认为是 run() 中的局部变量。
再接下来执行 r() 时,程序运行至 pos = pos + step 时,因为先前已经把 pos 归为 run() 中的局部变量,所以 python 会在 run() 中去找在赋值语句右面的 pos 的值,结果找不到,就会报错。
解决措施
在 python3 以后,在 pos = pos + 1 之前,使用语句 nonloacal pos 显式的指定 pos 不是闭包的局部变量。
In [14]: def boy(pos): ...: def run(step): ...: nonlocal pos ...: pos = pos + step ...: return pos ...: return run
In [15]: r = boy(0)
In [16]: r(10) Out[16]: 10
我们可以利用,闭包执行完后仍然能够保持住当前的运行环境。
演示代码如下:
In [14]: def boy(pos): ...: def run(step): ...: nonlocal pos ...: pos = pos + step ...: return pos ...: return run
In [15]: run = boy(0)
In [16]: run(10) Out[16]: 10
In [17]: run(20) Out[17]: 30
In [18]: run(10) Out[18]: 40
可以看出,返回的闭包 run 中保存了 pos的值,下次执行闭包会记住上次 pos 的值,这就是闭包的数据持久化功能。文章参考:https://www.cnblogs.com/JohnABC/p/4076855.html
本文分享自 程序员郭震zhenguo 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!