1、定义
在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包。
- 必须有一个嵌套函数(函数在函数内部)
- 嵌套函数必须引用在封闭函数中定义的值
- 封闭函数必须返回嵌套函数
2、闭包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| """ 闭包 """ from tool import topic
def func_A(a: int):
def func_B(b: int): return a + b
return func_B
@topic("Demo-1") def demo_1(): my_func = func_A(5) ret = my_func(10) print(f"ret={ret}") pass
if __name__ == "__main__": demo_1() pass
|
嵌套函数可以访问封闭范围的变量。这些非本地变量是只读的,并且我们必须将它们明确声明为非本地变量(使用nonlocal
关键字)才能进行修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| """ 闭包 """ from tool import topic
def func_C(c: int):
def func_D(): nonlocal c c = c**2 print(f"In func_D, c={c}")
print(f"In func_C before call func_D, c={c}") func_D() print(f"In func_C after call func_D, c={c}") pass
@topic("Demo-1") def demo_1(): func_C(10) pass
if __name__ == "__main__": demo_1() pass
|
闭包比普通的函数多了一个 __closure__
属性,该属性记录着自由变量的地址。当闭包被调用时,系统就会根据该地址找到对应的自由变量,完成整体的函数调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| """ 闭包 """ from tool import topic
def nth_power(exponent): """ 闭包可以避免使用全局值,并提供某种形式的数据隐藏。 """
def exponent_of(base): return base**exponent
return exponent_of
@topic("Demo-1") def demo_1(): sqr = nth_power(2) cube = nth_power(3) print(f"sqr(5)={sqr(5)}") print(f"cube(5)={cube(5)}")
print(sqr.__closure__) print(sqr.__closure__[0].cell_contents) print(cube.__closure__[0].cell_contents) pass
if __name__ == "__main__": demo_1() pass
|