zoukankan      html  css  js  c++  java
  • python 闭包

    首先提一下外函数和内函数:如果在一个函数的内部定义了另一个函数,外部的我们叫它外函数,内部的我们就叫它内函数。

     示例一:

    #函数的局部作用域导致出错
    def
    outer_fun(): def inner_fun(): print('Nice to meet you!') inner_fun()
    ------------------------ NameError: name 'inner_fun' is not defined

     示例二:

    #通过外函数返回内函数的引用来执行内函数
    def
    outer_fun(): def inner_fun(): print('Nice to meet you!') return inner_fun outer_fun()() # 或者 # fun = outer_fun() # fun() ---------------------- Nice to meet you!

    闭包:

    在一个外函数中定义了一个内函数,内函数里运用了外函数定义的局部变量(这时这个外函数的局部变量就成了内函数的环境变量),并且外函数的返回值是内函数的引用(这个引用的对象中包含了函数的代码和它的环境变量),这样就构成了一个闭包。即闭包 = 内部函数 + 环境变量。

    我们知道,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但对闭包而言,如果外函数在结束的时候发现有自己的局部变量将来会在内部函数中用到,就先把这个局部变量绑定给内部函数,再结束自己。

    示例三:

    #此时闭包的环境变量a是全局变量中定义的a = 1
    def
    outer_fun(): def inner_fun(): print(a) return inner_fun a = 1 outer_fun()() -------------------- 1

    示例四:

    #此时闭包中的环境变量a是外部函数中定义的a = 0
    def
    outer_fun(): a = 0 def inner_fun(): print(a) return inner_fun a = 1 outer_fun()() -------------------- 0

    从中也可以发现,当形成闭包之后闭包内函数的执行将不受闭包之外变量的影响。

    如果内部函数想要改变它的环境变量(外部函数定义的局部变量),需要使用nonlocal先声明该变量。看下面这个例子:

    示例五:

    def outer_fun(a):
        def inner_fun():
            nonlocal a 
            a += 1
            print(a)
        return inner_fun
    
    a = outer_fun(0)
    a()
    a()
    
    ---------------
    1
    2

    无环境不闭包,例如下面这个没有形成闭包的示例(属性__closure__包含函数所需的环境变量):

    示例六:

    #变量a并不是内部函数的环境变量,而是在内部函数中定义的局部变量
    def
    outer_fun(): a = 0 def inner_fun(): a = 1 return inner_fun f = outer_fun() print(f.__closure__) -------------- None

     示例七:

    def outer_fun():
        a = 0
        def inner_fun():
            print(a)
        return inner_fun
    f = outer_fun()
    print(f.__closure__)
    
    ---------------------
    (<cell at 0x00000168C565EC48: int object at 0x00007FFB889CEEE0>,)

    总结

    闭包所形成的特点就是,外函数将内函数以及它的环境变量一起打包,最后作为返回之前返回出去。并且在同一个外函数的环境下多次调用内函数时,如果内函数改变了环境变量,那么该改变将保存,例如示例五。

  • 相关阅读:
    UVa OJ 148 Anagram checker (回文构词检测)
    UVa OJ 134 LoglanA Logical Language (Loglan逻辑语言)
    平面内两条线段的位置关系(相交)判定与交点求解
    UVa OJ 130 Roman Roulette (罗马轮盘赌)
    UVa OJ 135 No Rectangles (没有矩形)
    混合函数继承方式构造函数
    html5基础(第一天)
    js中substr,substring,indexOf,lastIndexOf,split等的用法
    css的textindent属性实现段落第一行缩进
    普通的css普通的描边字
  • 原文地址:https://www.cnblogs.com/huwt/p/11184415.html
Copyright © 2011-2022 走看看