闭包——学习笔记

学习闭包,逻辑有点混乱,现在记录一下学习过程。
功能:实现函数容器内保存一个变量,记录该函数执行状态;
原理:看到一篇bloghttps://www.cnblogs.com/jiangyuzhen/p/10922546.html

总结一下闭包的作用

  • 读取函数内部的变量
  • 将变量的值始终保存在内存中

一般来讲,当函数执行完毕之后,函数内部的局部活动对象就会被销毁,内存中仅保存全局作用域,即js的内存回收机制。
如果这个函数内部又嵌套了另一个函数,而这个函数是有可能在外部被调用到的.并且这个内部函数又使用了外部函数的某些变量的话.这种内存回收机制就会出现问题。如果在外部函数返回后,又直接调用了内部函数,那么内部函数就无法读取到他所需要的外部函数中变量的值了.所以js解释器在遇到函数定义的时候,会自动把函数和他可能使用的变量(包括本地变量和父级和祖先级函数的变量(自由变量))一起保存起来.也就是构建一个闭包,这些变量将不会被内存回收器所回收,只有当内部的函数不可能被调用以后(例如被删除了,或者没有了指针),才会销毁这个闭包,而没有任何一个闭包引用的变量才会被下一次内存回收启动时所回收。

python应该和js类似,都有垃圾回收机制,所以,可以这么写:

def wrpper():
    n=0
    def inside():
        print(n)
        n=n+1
        return None
    return inside



if __name__ == '__main__':
    a=wrpper()
    a()
    a()
    a()

结果报错:UnboundLocalError
在另一篇博客上找到答案https://www.jianshu.com/p/02c19aaf33f6

在python中变量是不需要提取声明的,一个变量第一次赋值就是声明了这个变量。a = a + 1 这个表达式的意思是声明一个局部变量a并将它 + 1后赋值给它自己,而此时a 还没有初始化(没有被赋值),所以会出现报错 UnboundLocalError: local variable 'a' referenced before assignment
虽然闭包中内部函数可以引用外部函数的变量,但a = a + 1 中“=”号前的a覆盖掉了外部函数f中的局部变量a=1,所以a = a + 1就会出现未定义的错误。只要外部函数f中的局部变量a 不被覆盖就可以解决问题。

python 如何声明仅仅引用上一级的父亲变量?我还想不出来
所以根据上一篇博客给出的方法,改为对可变对象的引用:

def wrpper():
    n=[0]
    def inside():
        print(n[0])
        n[0] = n[0]+1
        return None
    return inside



if __name__ == '__main__':
    a=wrpper()
    a()
    a()
    a()

返回结果:0,1,2 符合预期

posted @ 2020-07-02 10:16  Bravo_Jack  阅读(111)  评论(0编辑  收藏  举报