闭包这个概念在 JavaScript 中讨论和使用得比较多,不过在 Python 中却不是那么显而易见,之所以说“不是那么”,是因为即使用到了,也没用注意到而已,比如定义一个 Decorator 时,就已经用到闭包了。网上对闭包的各种解释,感觉非常晦涩,在这里谈谈我的浅显认识:要形成闭包,首先得有一个嵌套的函数,即函数中定义了另一个函数,闭包则是一个集合,它包括了外部函数的局部变量,这些局部变量在外部函数返回后也继续存在,并能被内部函数引用。
这是个经常使用到的例子,定义一个函数 <code>generate_power_func</code>,它返回另一个函数,现在闭包形成的条件已经达到。
对于内部函数 <code>nth_power</code>,它能引用到外部函数的局部变量 <code>n</code>,而且即使 <code>generate_power_func</code> 已经返回。把这种现象就称为闭包。具体使用一下。
从结果可以看出,当 <code>generate_power_func(4)</code> 执行后, 创建和返回了 <code>nth_power</code> 这个函数对象,内存地址是 0x2C090C8,并且发现 <code>raised_to_4</code> 和它的内存地址相同,即 <code>raised_to_4</code>只是这个函数对象的一个引用。先在全局命名空间中删除 <code>generate_power_func</code>,再试试会出现什么结果。
啊哈,居然没出现错误, <code>nth_power</code> 是怎么知道 <code>n</code> 的值是 4,而且现在 <code>generate_power_func</code> 甚至都不在这个命名空间了。对,这就是闭包的作用,外部函数的局部变量可以被内部函数引用,即使外部函数已经返回了。
现在知道闭包是怎么一回事了,那就到看看闭包到底是怎么回事的时候了。Python 中函数也是对象,所以函数也有很多属性,和闭包相关的就是 <code>__closure__</code> 属性。<code>__closure__</code> 属性定义的是一个包含 cell 对象的元组,其中元组中的每一个 cell 对象用来保存作用域中变量的值。
本文转自 h2appy 51CTO博客,原文链接:http://blog.51cto.com/h2appy/1942090,如需转载请自行联系原作者