Python连载18-closure闭包解释及其注意点

论坛 期权论坛 期权     
傅里叶变换   2019-6-30 05:31   2410   0
一、闭包
1.定义:当一个函数在内部定义函数,并且内部的函数应用外部函数的参数或者局部变量,当内部函数被当做返回值的时候,相关参数和变量保存在返回的函数之中,这种结果,叫做闭包。
2.例子:连载17中的myF4就是一个典型的例子。
3.闭包常见的坑
  1. def count():
复制代码
  1.     #定义列表
复制代码
  1.     fs = []
复制代码
  1.     for i in range(1,4):
复制代码
  1.         def f():
复制代码
  1.             return i*i
复制代码
  1.         fs.append(f)
复制代码
  1.         #按照我们的预期,应该是fs=[f,f,f].其中f中一次包含1,4,9,这样才对,但实际结果不是,我么接着看
复制代码
  1.     return fs
复制代码
  1. f1,f2,f3 = count()
复制代码
  1. print(f1(),f2(),f3())
复制代码


不是我们预期的1  4  9。
(1)原因分析:返回函数引用了变量i,i并非立即执行,而是等到三个函数都返回的时候才统一执行,此时i已经变为3,最终调用的时候却反回了3*3.
(2)总结:返回闭包的时候,返回函数不能引用任何循环变量了
(3)解决方案:再创建一个函数,用该函数的参数绑定循环变量的当前值,无论该循环变量以后如何改变,已经绑定的函数参数值不变。
改进代码:
  1. def count2():
复制代码
  1.     def f(j):
复制代码
  1.         def g():
复制代码
  1.             return j*j
复制代码
  1.         return g
复制代码
  1.     fs = []
复制代码
  1.     for i in range(1,4):
复制代码
  1.         fs.append(f(i))
复制代码
  1.         #我们进行了传参,因此j就固定下来,它就执行了j
复制代码
  1.     return fs
复制代码
  1. f4,f5,f6 = count2()
复制代码
  1. print(f4(),f5(),f6())
复制代码


二、装饰器
  1. def hello():
复制代码
  1.     print("我是一个程序")
复制代码
  1. f = hello
复制代码
  1. f()
复制代码
  1. hello()
复制代码
  1. #用id来证明f和hello是一个函数
复制代码
  1. print(id(f),id(hello))
复制代码


三、源码:
d20_2_closure_interpretation
地址:https://github.com/ruigege66/Python_learning/blob/master/d20_2_closure_interpretation
2.CSDN:https://blog.csdn.net/weixin_44630050(心悦君兮君不知-睿)
3.博客园:https://www.cnblogs.com/ruigege0000/
4.欢迎关注微信公众号:傅里叶变换,后台回复”礼包“,获取大数据学习资料。


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:6
帖子:11
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP