Python 闭包

参考:python 闭包理解 (推荐)

每个函数都有一个叫做 __closure__ 的属性,一般情况下这个属性为None。

但如果在一个外函数中定义了一个内函数,且内函数里使用了外函数的变量,那这个内函数的 __closure__就不再是None,而是有了真实内容,这些内容是所有外函数的变量的集合,也就是闭包。在内函数中使用外函数的变量时,实际上就是从这个 __closure__中取变量的。

示例1:

1
2
3
4
5
6
7
8
9
10
11
12
def f1():
    b = 1
    def f2():
        c = b * 3
        print('c: ', c)
    f2()
 
if __name__ == '__main__':
    f1()
 
# 输出:
# c:  3

 

需要注意的是,在内函数中,不能直接对外函数的变量进行赋值,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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关键字,上面例子可以修改下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

 

如果外函数的变量是列表,可以直接在内函数进行操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def f1():
    b = []
    def f2():
        b.append(1)
        print('内函数 b: ', b)
    f2()
    print('外函数 b: ', b)
 
if __name__ == '__main__':
    f1()
 
# 输出:
# 内函数 b:  [1]
# 外函数 b:  [1]

 

posted @   Picassooo  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
历史上的今天:
2020-08-14 LSTM的计算过程,权重参数数目,weight_ih_l0,weight_hh_l0
2020-08-14 超详细的Pycharm远程连接服务器教程 (Mac Pro)
点击右上角即可分享
微信分享提示