• 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]
    
  • 相关阅读:
    关于BindingSource的ListChange事件
    .Net 中Textbox控件的数据绑定
    Google Chrome OS Open Source Project Announcement
    ajax从基础开始
    如何处理Windows Forms程序中未处理的异常
    Chrome的一个bug? 大家看看
    Extjs学习笔记之二——初识Extjs之Form
    SQLite3简介及在.Net程序中的使用
    Extjs学习笔记之一——初识Extjs之MessageBox
    Extjs学习笔记之三——更多的表单项
  • 原文地址:https://www.cnblogs.com/picassooo/p/16585212.html
Copyright © 2020-2023  润新知