Python 闭包坑点

640

闭包坑点

上篇参考:Python 闭包使用注意点,接下来,介绍使闭包,经常会犯的一个错误:演示代码如下,


 
  1. In [6]: def boy(pos):

  2. ...: def run(step):

  3. ...: pos = pos + step

  4. ...: return pos

  5. ...: return run

  6. ...:


  7. In [7]: r = boy(0)


  8. In [9]: r(10)

  9. ---------------------------------------------------------------------------

  10. UnboundLocalError Traceback (most recent call last)

  11. <ipython-input-9-5a4ba556b403> in <module>

  12. ----> 1 r(10)


  13. <ipython-input-6-9b6d05d20cb3> in run(step)

  14. 1 def boy(pos):

  15. 2 def run(step):

  16. ----> 3 pos = pos + step

  17. 4 return pos

  18. 5 return run


  19. UnboundLocalError: local variable 'pos' referenced before assignment



640

分析原因

python 规则指定所有在赋值语句左面的变量都是局部变量,则在闭包 run() 中,变量 pos 在赋值符号"="的左面,被 python 认为是 run() 中的局部变量。


再接下来执行 r() 时,程序运行至 pos = pos + step 时,因为先前已经把 pos 归为 run() 中的局部变量,所以 python 会在 run() 中去找在赋值语句右面的 pos 的值,结果找不到,就会报错。



640

解决措施

在 python3 以后,在 pos = pos + 1 之前,使用语句 nonloacal pos 显式的指定 pos 不是闭包的局部变量。


 
  1. In [14]: def boy(pos):

  2. ...: def run(step):

  3. ...: nonlocal pos

  4. ...: pos = pos + step

  5. ...: return pos

  6. ...: return run


  7. In [15]: r = boy(0)


  8. In [16]: r(10)

  9. Out[16]: 10


我们可以利用,闭包执行完后仍然能够保持住当前的运行环境。

演示代码如下:



 
  1. In [14]: def boy(pos):

  2. ...: def run(step):

  3. ...: nonlocal pos

  4. ...: pos = pos + step

  5. ...: return pos

  6. ...: return run


  7. In [15]: run = boy(0)


  8. In [16]: run(10)

  9. Out[16]: 10


  10. In [17]: run(20)

  11. Out[17]: 30


  12. In [18]: run(10)

  13. Out[18]: 40

可以看出,返回的闭包 run 中保存了 pos的值,下次执行闭包会记住上次 pos 的值,这就是闭包的数据持久化功能。文章参考:https://www.cnblogs.com/JohnABC/p/4076855.html




更多文章,点击图片


640?wx_fmt=png


640?wx_fmt=png


640?wx_fmt=jpeg

长按订阅


smiley_66.png点个好看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值