闭包

闭包

  • 什么是闭包?

    • 闭包是内层函数对外层函数非全局变量的引用(使用),闭包只能存在于嵌套函数中
  • 闭包的作用?

    • 保证数据的安全,自由变量不会在内存中消失,而且全局引用不到。
    • 闭包中外层函数中的变量也称自由变量,这个自由变量会与内层函数产生一个绑定关系,使得自由变量不会在内存中消失,内层函数可以调用到外层函数的自由变量。
  • 练习题:整个历史中某个商品的平均收盘价(就是从这个商品一开始出现,每天记录当天的价格,然后计算当天的平均值:平均值靠考虑直至目前位置所有的价格)

    # 方式一
    li=[]     #全局变量数据不安全
    def func(s1):
        li.append(s1)
        return sum(li)/len(li)
    while True:
        s1 = int(input('请输入今日价格:'))
        # li.append(546)      #不安全,可以随便对列表进行操作
        print(f'今日评价收盘价是{func(s1)}')
        print(li)
        
    # 方式二    此方法行不通
    def func(s1):
        li = []    #函数内部相当于是一个临时名称空间,当执行结束后,就会消失
        li.append(s1)
        return sum(li)/len(li)
    while True:
        s1 = int(input('请输入今日价格:'))
        print(f'今日评价收盘价是{func(s1)}')
        
    
    #方式三 闭包
    def func():
        li = []
        def func1(s1):
            nonlocal li
            li.append(s1)
            return sum(li)/len(li)
        return func1
    
    s=func()    #切记此处必须把放在外面,如果放在循环里面,则每次都会调用一个新的函数
    while True:
        s1 = int(input('请输入今日价格:'))
        print(f'今日评价收盘价是{s(s1)}')
    
    
  • 如何判断一个函数是不是闭包:

    1. 是嵌套函数

    2. 内层函数对外层自由变量进行引用

    3. def func():
          li = []
          def func1(s1):
              nonlocal li
              li.append(s1)
              return sum(li)/len(li)
          return func1
      
      s=func()    #切记此处必须把放在外面,如果放在循环里面,则每次都会调用一个新的函数
      while True:
          s1 = int(input('请输入今日价格:'))
          print(f'今日评价收盘价是{s(s1)}')
          print(s.__code__.co_freevars)    #如果有返回值就证明有自由变量
      
  • 获取闭包函数的自由变量:函数句柄.code.co_freevars,返回元组('a', 'name')

    def wrapper(a):
        name='xiaoxiannv'
        def inner():
            print(name)
            print(a)
        return inner
    ret=wrapper('hhhh')
    
    print(ret.__code__.co_freevars)   #获取自由变量
    得:
    ('a', 'name')
    
posted @ 2021-06-03 13:36  刘家小仙女  阅读(57)  评论(0编辑  收藏  举报