引用自由变量的镶嵌函数才是闭包 Python 的函数有一个只读属性 __closure__,存储的就是函数所引用的自由变量,仅是嵌套函数,它的 __closure__ 应该是 None # 一.闭包的运行过程 def test1(number): # 运行1 print("ok") # 运行4 def test2(a): number = 5 print(a,number) number = 6 print(number) # 运行2 print(number) # 运行3,导出内部方法,不写访问不了,相当于入口 return test2 # test1(4)代表访问test1这个函数输入参数4,他会返回一个test2方法,加(7)就进入test2方法 # a = test1(4)(7) # 返回 # ok # 4 # 7 5 # 6 # 二.闭包的注意事项: # 1.内部函数只能读取自由变量值,无法修改自由变量值,且如果内部对自由变量先打印后赋值,由于python命名空间规则,会认定这个变量是局部变量,从而报错 # 2.自由变量在函数外部无法使用,会报错 # print(number) NameError: name 'number' is not defined # 3.由于函数命名空间查找规则,自由变量先于全局变量被找到,因此在函数外部改自由变量时,不起效果,只是相当于创建全局变量 # 4.自由变量容易出现的问题:任何方法在调用前都只是加载不会执行这个情况后即函数在没有执行前,内部代码不执行 (里面涉及pyhon函数作用域问题,我看了https://www.jianshu.com/p/f38fbcdde765这位大佬写的,感觉get了许多知识) # 4对应:对应实例 fs = [lambda j:i*j for i in range(6)] print(fs[0](2)) # 以上等价于 for i in range(6): j = 2 # test只被声明,未被调用 def test(): global j j = i*j print(j) # 如果此处加test(),能正常产生结果,因为每次i改值都被调用函数 # 此时调用i已经指向5 test() # 10 10 # 三.内部函数更改自由变量 # 1.在外部函数内将自由变量放入可变数据类型里,此时更改不会对自由变量造成影响 # 2.在内部函数里使用关键字nonlocal 形式 nonlocal 自由变量 (理解:non + local 告诉解释器不是局部变量) # 实例:使用可变数据类型 def f1(a): a = [a] print(a) print(1) def f2(b): b = a[0] print(2) print(b) print(3) return f2 b = f1('a')('b') def f1(a): a = {1:a} print(a) print(1) def f2(b): b = a[1] print(2) print(b) print(3) return f2 b = f1('a')('b') # 实例:使用关键字 def f1(a): print(a) print(1) def f2(b): nonlocal a b = a print(2) print(b) print(3) return f2 b = f1('a')('b')