Python中的闭包

php对闭包的定义是匿名函数,我之前对python闭包的理解是:外部函数以内部函数作为返回值,称之为闭包!!!(错的,1、不是以内部函数作为返回值,是返回内部函数的引用;2、闭包是对变量作用域的应用)
最近在重新看Python一些基础的东西,突然发现之前自己对python闭包的概念理解是特么错的!

在解释闭包之前,先说一个定义:Python中如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数。

闭包:

在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。(要知道必须要用到外部的函数临时变量才能称之为闭包,闭包是对变量作用域的应用,而不是简单地返回一个函数)

有点青涩难懂,上代码吧:

# outer是外部函数 a和b都是外函数的临时变量(你也可以称之为环境变量)
def outer( a ):
    b = 10
    # inner是内函数
    def inner():
        #在内函数中 用到了外函数的临时变量
        print(a+b)
    # 外函数的返回值是内函数的引用
    return inner

if __name__ == '__main__':
    # 在这里我们调用外函数传入参数5
    #此时外函数两个临时变量 a是5 b是10 ,并创建了内函数,然后把内函数的引用返回存给了demo
    # 外函数结束的时候发现内部函数将会用到自己的临时变量,这两个临时变量就不会释放,会绑定给这个内部函数
    demo = outer(5)
    # 我们调用内部函数,看一看内部函数是不是能使用外部函数的临时变量
    # demo存了外函数的返回值,也就是inner函数的引用,这里相当于执行inner函数
    demo() # 15

    demo2 = outer(7)
    demo2()#17

如何在闭包的内部函数修改外部函数的临时变量:

1、在python3中,可以用nonlocal 关键字声明 一个变量, 表示这个变量不是局部变量空间的变量,需要向上一层变量空间找这个变量。

2、使用可变类型数据,比如list和dict!

# outer是外部函数 a和b都是外函数的临时变量
def outer( a ):
    b = 10  # a和b都是闭包变量
    c = [a] #这里对应修改闭包变量的方法2
    # inner是内函数
    def inner():
        #内函数中想修改闭包变量
        # 方法1 nonlocal关键字声明
        nonlocal  b
        b+=1
        # 方法二,把闭包变量修改成可变数据类型 比如列表
        c[0] += 1
        print(c[0])
        print(b)
    # 外函数的返回值是内函数的引用
    return inner

if __name__ == '__main__':

    demo = outer(5)
    demo() # 6  11

还有一点需要注意:
使用闭包的过程中,一旦外函数被调用一次返回了内函数的引用,虽然每次调用内函数,是开启一个函数执行过后消亡,但是闭包变量实际上只有一份,每次开启内函数都在使用同一份闭包变量

def outer(x):
    def inner(y):
        nonlocal x
        x+=y
        return x
    return inner

a = outer(10)
print(a(1)) //11
print(a(3)) //14
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 目录 作用域(scope) 闭包的定义 闭包的作用 总结 2018.4.15更新了对于函数作用域的理解内容 1.作...
    苦逼李阅读 694评论 1 0
  • 什么是闭包?闭包有什么用?为什么要用闭包?今天我们就带着这3个问题来一步一步认识闭包。 闭包和函数紧密联系在一起,...
    码农小杨阅读 366评论 0 2
  • 原文出处: cicaday Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需...
    PyChina阅读 409评论 0 1
  • 闭包(closure)是函数式编程的重要的语法结构。闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性。 ...
    田飞雨阅读 3,332评论 5 13
  • 导读:Python中的装饰器经常用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。本文从闭包的概念...
    zgjx阅读 442评论 0 3