Python: 闭包

闭包的概念

关于什么是闭包,下面是百度百科的解释

闭包是可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)

在Python当中,当函数A返回函数B时, A中的参数和变量都保持在返回函数B中(通过引用计数实现),函数B就是一个闭包,函数A的参数也称为自由变量。

闭包的一些特性

惰性求值

>>> def ret_func(a):
...     def func():
...         return a
...     return func
...
>>> func1 = ret_func(2)
>>>
>>> func1()
2

可以看到,只有在函数调用的时候,才执行函数func1,这就是惰性求值。这个在Django当中的数据查询时的惰性查询就是通过闭包的方式实现的。
每一次调用都返回一个新的函数

>>> def ret_func(a):
...     def func():
...         return a
...     return func
...
>>> func1 = ret_func(2)
>>> func2 = ret_func(2)
>>>
>>> func1 != func2
True

很明显func1 != func2,这也印证每一次调用返回的都是一个新的函数

闭包要注意的问题

不要在闭包当中引用任何会发生改变的变量

在上面的代码当中,函数ret_func_list返回一个list里面保存了3个函数变量,这4个函数都共同的引用了循环变量i, 也就是说它们共享着同一个变量i,i是会改变的,当函数调用时,循环变量i已经是等于2了,因此3个函数返回的都是4。如果,需要在闭包使用循环变量的值的话,把循环变量作为闭包的默认参数或者是通过偏函数来实现。实现的原理也很简单,就是把当把循环变量当参数传入函数时,会申请新的内存。示例代码如下

>>> def ret_func2():
...     arr = []
...     for i in range(4):
...         arr.append(lambda i=i: i*i)
...     return arr
...
>>> results = ret_func2()
>>> func1 = results[0]
>>> func2 = results[1]
>>> func3 = results[2]
>>>
>>> func1()
0
>>> func2()
1
>>> func3()
4
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、python函数作用域LEGB python解释器查找变量的原则(顺序):L→E→G→BL:Local函数内部...
    风萧雨霖阅读 480评论 0 0
  • 闭包(closure)是函数式编程的重要的语法结构。函数式编程是一种编程范式 (而面向过程编程和面向对象编程也都是...
    Mr_Chen阅读 321评论 0 1
  • 我在博客中曾经介绍过两篇关于函数的文章,第一篇是 关于 Python 函数是第一类对象,第二篇是关于 Lambda...
    liuzhijun阅读 1,551评论 2 27
  • 闭包 所谓闭包,就是将组成函数的语句和这些语句的执行环境打包在一起时,得到的对象。 栗子1 上面这个函数有点纠结!...
    MJXH阅读 390评论 0 0
  • 1、盘面一览 周三开盘后创业板率先冲高不到20分钟,而后全天阴跌到收市,这也是量能限制下最有可能出现的走势,...
    阿凯古阅读 254评论 0 1