Python 闭包
参考:python 闭包理解 (推荐)
每个函数都有一个叫做 __closure__ 的属性,一般情况下这个属性为None。
但如果在一个外函数中定义了一个内函数,且内函数里使用了外函数的变量,那这个内函数的 __closure__就不再是None,而是有了真实内容,这些内容是所有外函数的变量的集合,也就是闭包。在内函数中使用外函数的变量时,实际上就是从这个 __closure__中取变量的。
示例1:
def f1():
b = 1
def f2():
c = b * 3
print('c: ', c)
f2()
if __name__ == '__main__':
f1()
# 输出:
# c: 3
需要注意的是,在内函数中,不能直接对外函数的变量进行赋值,示例如下:
def f1():
b = 1
def f2():
b = 2 # 这个b会被认为是内函数f2的局部变量,和外函数f1的b没有关系
print('内函数 b: ', b)
f2()
print('外函数 b: ', b)
if __name__ == '__main__':
f1()
# 输出:
# 内函数 b: 2
# 外函数 b: 1
因为在python3中,不能直接对外部变量进行写,如果直接写,它会认为你在重新定义一个内部函数的局部变量,并在接下来的访问中隐藏对外部同名变量的访问。如果确实需要写外部变量,需要先在使用前声明,使用nonlocal关键字,上面例子可以修改下:
def f1():
b = 1
def f2():
nonlocal b
b = 2 # 这个b是从__closure__中读取的,即是外函数f1的b
print('内函数 b: ', b)
f2()
print('外函数 b: ', b)
if __name__ == '__main__':
f1()
# 输出:
# 内函数 b: 2
# 外函数 b: 2
如果外函数的变量是列表,可以直接在内函数进行操作:
def f1():
b = []
def f2():
b.append(1)
print('内函数 b: ', b)
f2()
print('外函数 b: ', b)
if __name__ == '__main__':
f1()
# 输出:
# 内函数 b: [1]
# 外函数 b: [1]

浙公网安备 33010602011771号