Closure in Python   发布时间:2017-09-11 12:27:24

Closure in Python 闭包(closure)是一种引用了外部变量的函数对象,无论该变量所处的作用域是否还存在于内存中。

举例来说,函数 generate_power_func 返回了另一个函数:

def generate_power_func(n):

print "id(n): %X" % id(n)

def nth_power(x):

return x**n

print "id(nth_power): %X" % id(nth_power)

return nth_power

函数 nth_power 就是一个闭包,它可以访问定义在 generate_power_func 函数中的变量 n,显而易见如果缺少变量 n,函数 nth_power 将是一个不能执行的没有闭合的函数,这个不完整的函数 nth_power 需要变量 n 来让它变成一个完整的函数对象,这种函数就是闭包,换句话说是变量 n 封闭了函数 nth_power。

现在我们调用一下函数 generate_power_func,并将调用结果返回给一个变量 raised_to_4。

>>> raised_to_4 = generate_power_func(4)

id(n): 28F8A4

id(nth_power): B6CB4570

>>> repr(rasied_to_4)

'<function nth_power at 0xb6cb4570>'

结果是调用函数 generate_power_func(4) 将生成一个 nth_power 函数对象。现在我们将函数 generate_power_func 函数从全局命名空间删除。

>>> del generate_power_func

然后调用闭包函数 raised_to_4。

>>> rasied_to_4(2)

16

奇迹出现了,销毁函数 generate_power_func 并没有影响到函数 raised_to_4。我们在函数 generate_power_func 中定义变量 n,并且我们已经销毁了函数 generate_power_func,站群,为什么 raised_to_4 会知道变量 n=4?

这是因为函数对象 nth_power 是由 generate_power_func 产生的一个闭包,闭包会保留来自外围作用域变量的信息。

__closure__ 属性和 cell 对象

Python 中函数对象都拥有一个 __closure__ 属性。

__closure__ 对象返回一个由 cell 对象组成的元组,cell 对象记录了定义在外围作用域的变量信息。

>>> raised_to_4.__closure__

(<cell at 0xb6cb7f70: int object at 0x28f8a4>,)

>>> type(raised_to_4.__closure__[0])

<type 'cell'>

>>> raised_to_4.__closure__[0].cell_contents

4

正如所见,__closure__ 属性引用了一个 int 对象,这个 int 对象就是变量 n。对于那些不是闭包的函数对象来说,__closure__ 属性值为 None。

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:孝感网站制作 http://xiaogan.666rj.com