Python 中的闭包 —— Closure

闭包的概念

在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。
—— 维基百科)

用比较容易懂的人话说,就是当某个函数被当成对象返回时,夹带了外部变量,就形成了一个闭包。看例子。

In [15]: def func(name):
    ...:     def inner_func(age):
    ...:         print('name',name,'age',age)
    ...:     return inner_func
    ...:

In [17]: bb = func('Tom')

In [18]: bb
Out[18]: <function __main__.func.<locals>.inner_func>

In [19]: type(bb)
Out[19]: function

In [20]: bb(18)
name Tom age 18

这里面调用func的时候就产生了一个闭包——inner_func,并且该闭包持有自由变量——name,因此这也意味着,当函数func的生命周期结束之后,name这个变量依然存在,因为它被闭包引用了,所以不会被回收。

另外再说一点,闭包并不是Python中特有的概念,所有把函数做为一等公民的语言均有闭包的概念。


闭包的作用

闭包的最大特点是可以将父函数的变量与内部函数绑定,并返回绑定变量后的函数(也即闭包),此时即便生成闭包的环境(父函数)已经释放,闭包仍然存在,这个过程很像类(父函数)生成实例(闭包),不同的是父函数只在调用时执行,执行完毕后其环境就会释放,而类则在文件执行时创建,一般程序执行完毕后作用域才释放,因此对一些需要重用的功能且不足以定义为类的行为,使用闭包会比使用类占用更少的资源,且更轻巧灵活,现举一例:假设我们仅仅想打印出各类动物的叫声,分别以类和闭包来实现:

类:

In [23]: class Animal():
    ...:     def __init__(self,animal):
    ...:         self.animal = animal
    ...:     def sound(self,voice):
    ...:         print(self.animal,':',voice,'...')
    ...:

In [24]: dog = Animal('dog')

In [25]: dog.sound('wang~wang~')
dog : wang~wang~ ...

In [26]: dog.sound('wo~wo~')
dog : wo~wo~ ...

闭包:

In [28]: def voice(animal):
    ...:     def sound(voc):
    ...:         print(animal,':',voc,'...')
    ...:     return sound
    ...:

In [29]: dog = voice('dog')

In [30]: dog('wangwangwang~')
dog : wangwangwang~ ...

In [31]: type(dog)
Out[31]: function

In [32]: dog
Out[32]: <function __main__.voice.<locals>.sound>

可以看到输出结果是完全一样的,但显然类的实现相对繁琐,且这里只是想输出一下动物的叫声,定义一个Animal 类未免小题大做,而且 voice 函数在执行完毕后,其作用域就已经释放,但Animal 类及其实例 dog 的相应属性却一直贮存在内存中

In [33]: id(Animal.sound)
Out[33]: 2044388328584

而这种占用对于实现该功能后,则是没有必要的。

除此之外,闭包还有很多其他功能,比如用于封装等,另外,闭包有效的减少了函数参数的数目,这对并行计算非常有价值,比如可以让每台电脑负责一个函数,然后串起来,实现流水化的作业等。

Python 的闭包和装饰器

说说Python中的闭包 - Closure

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值