0%

【Python笔记】闭包

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