• 闭包


    closure:闭包的意思
    闭包特点:
      1.>函数的嵌套定义,就是函数定义里面有另外一个函数的定义
      2.>外部函数返回内部函数的引用<引用地址>
      3.>内部函数可以使用外部函数提供的自由变量/环境变量 <顺序是先去找自己的位置参数,看看是否有同名,如果没有就向外扩展一层,继续这个过程.直到找到>
    这就是闭包的三个特点

    概念:内部函数 + 自由变量 构成的 整体 这是IBM 开发网站的一个说法
    理解:内部函数 + 外部函数提供给内部函数调用的参数.

    def func(num1):
        # 外部函数  的变量称之为自由变量/环境变量 内部函数也可以使用
        print('in func', num1)
    
        def func_in(num2):
            print('in func_in', (num1 + num2))
    
        # return func_in()# 这样就会调用func_in函数了
        # 返回func_in的引用地址 外部就可以进行调用func_in函数了
        return func_in
    
    
    # 因为func_in函数并没有被调用
    # func()  # in func
    # 接收外部函数func 返回值return是 内部函数func_in的引用
    f = func(99)
    f(100)

    闭包求线性方程:

    # ---------------------普通函数实现---------------------------------->
    # def line1(k, x, b):
    #     print('y = %d' % (k * x + b))
    #
    #
    # line1(1, 100, 1)
    # line1(1, 50, 1)
    # ---------------------------闭包实现-------------------------------->
    
    
    def line(k, b):
        def line_in(x):
            print('y = %d' % (k * x + b))
    
        return line_in
    
    
    # l1 = line(1, 1)
    # l1(100)
    # l1(50)
    
    l2 = line(2, 2)
    l2(100)
    l2(50)
    
    """
    l1,l2一样的代码,一样的函数参数,结果不一样,因为他们的环境变量/自由变量不一样
    闭包的概念:自由变量 + 内部函数
    """

    修改自由变量:

    # -----------------------------------------------修改自由变量:了解即可---------------------------------->
    def line(k, b):
        # data = [k]
        def line_in(x):
            # py3 提供的关键字 专门用来修改自由变量
            # 非本地变量  非本地不一定是全局变量,也可能是另外一个函数内部的内部变量<本地变量>
            nonlocal k
            # py2中没有这个关键字,只能将需要修改的变量放到列表中<间接>
            # data[0] += 1
            k += 1  # 不可变类型的k需要使用nonlocal 可变类型<就是[],{},字典等,>的不需要加nonlocal
    
            print('y = %d' % (k * x + b))
    
        return line_in
    
    
    l1 = line(1, 1)
    # l1(9)  # local variable 'k' referenced before assignment 本地变量在赋值之前被引用了
    
    # ------------------------扩展: 查看闭包中的资自由变量的值--------------------------->
    
    # print(l1.__closure__)
    # # (<cell at 0x0000017096A086A8: int object at 0x00000000658460E0>,
    # <cell at 0x0000017096A08708: list object at 0x00000170969D4C08>,
    # <cell at 0x0000017096A086D8: int object at 0x00000000658460E0>)
    # print(l1.__closure__[0].cell_contents)
    # print(l1.__closure__[1].cell_contents)
    # print(l1.__closure__[2].cell_contents)
    
    """
    推荐的经典书籍:
    《流畅的python》
    《Python核心编程》 第二版  不要看第三版 
    
    要求:硬着头皮看两遍
    
    """
    
    
    def make_avg():
        data = list()
    
        def addnumber(value):
            data.append(value)
            total = sum(data)
            # print(data)  加print进行调试理解
            return total / len(data)
    
        return addnumber
    
    
    # myavg = make_avg()
    # print(myavg(100))
    # print(myavg(200))
    # -------------------------------------------可变类型与不可变类型----------------------------------------------------->
    # str1 = 'lll'
    # str1[0]=6  # TypeError: 'str' object does not support item assignment  变量创建之后它内部的元素不能二次赋值就是  不可变类型
    
    list1 = [1, 2, 3]
    list1[0] = 33  # 内部元素可以被二次赋值,就是可变类型
  • 相关阅读:
    [转载]我的WafBypass之道(Misc篇)
    7.3 使用while 循环来处理列表和字典
    7-4__7-7练习
    7.2 while 循环
    第 7 章 用户输入和while 循环
    6.字典练习
    6.4 嵌套
    6.3 遍历字典
    6.2练习
    第 6 章 字典
  • 原文地址:https://www.cnblogs.com/huaibin/p/12101060.html
Copyright © 2020-2023  润新知