导航

闭包

Posted on 2019-03-25 23:19  菜花教授  阅读(92)  评论(0编辑  收藏  举报

闭包:  

  1. 内层函数使用了外层函数的局部变量
  2. 外层函数吧内层函数返回出来
  3. 这个内层函数加做闭包函数

闭包的特点:

  1. 内层函数使用了外层函数的变量,
  2. 这个变量与内层函数发生了绑定关系,
  3. 延长了他的生命周期

 

魔法方法__ closure __, 查看闭包函数使用过的变量

 1 def outer():
 2     a = 110
 3     def inner():
 4         def small():
 5             nonlocal a
 6             a = 1
 7         return small
 8     return inner
 9 
10 res = outer()
11 func = res()
12 func()
13 # __closure__获取闭包函数使用过的变量
14 # 返回一个元祖, 里面每一个元素是使用过的变量,
15 
16 print(func.__closure__)         # (<cell at 0x0000028C3ED19E28: int object at 0x0000000055AE6C10>,)
17 
18 
19 # cell_contents 是单元cell的一个属性, 获取保存的外部函数的变量
20 # 存放离得最近的外层函数的变量,或者最后一次nonlocal声明修改的变量,
21 # 若是外层函数的变量内层没有使用过, 将不存在这里
22 
23 print(func.__closure__[0].cell_contents)        # 1

 

 

保存离得最近的那个外层函数的变量

 

def outer():
    a = 1
    def inner():
        a = 2
        def small():
            a = 3
            def func():
                print(a)
            return func
        return small
    return inner

res = outer()()()

# 保存离得最近的那个外层函数的变量
print(res.__closure__[0].cell_contents)     # 3

 

保存最后一次nonlocal声明修改的变量

 

 1 def outer():
 2     a = 1
 3     def inner1():
 4         nonlocal a
 5         a = 1000
 6 
 7         def small():
 8             b = a
 9         return small
10 
11     def inner2():
12         print(a)
13     return inner1, inner2
14 
15 
16 func1, func2 = outer()
17 func3 = func1()
18 
19 # 三个内层函数都使用了a变量
20 # 由于inner1使用nonlocal声明修改, 并且执行func1()了
21 # 这三个内层函数保存的都是inner1声明修改的a变量
22 
23 print(func1.__closure__[0].cell_contents)       # 1000
24 print(func2.__closure__[0].cell_contents)       # 1000
25 print(func3.__closure__[0].cell_contents)       # 1000

 

测试是不是闭包:

 1 def outer():
 2     a = 1
 3     def inner():
 4         print(a)
 5     return inner
 6 
 7 
 8 res = outer()
 9 
10 # 判断是不是闭包函数
11 print(res.__closure__[0].cell_contents)
12 测试是不是闭包
13     内层函数.__closure__
14     返回是一个元祖, 是闭包
15     如果是None , 就不是闭包