什么是闭包

闭包 ( closure ) 是 词法闭包 ( Lexical Closure ) 的简称,是指引用了自由变量的函数。这些被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。

闭包的条件

  • 在一个内部函数中对外部作用域变量进行引用:自由变量对引用
  • 嵌套函数

闭包对最大特点就是可以将父函数的变量域内函数绑定,并且返回绑定变量后的函数【带参装饰器就是更根据这个实现的】,因为引用了其他函数内部变量。在正常情况下,函数运行完后就会被回收,但是 使用闭包的不会,它的函数生命周期得到了延续,不会被垃圾回收机制 回收 所以在使用闭包的时候要注意,不要轻易使用闭包
如果在使用的时候 需要修改变量 可以使用nonlocal 关键字来达到效果

  1. def outer(x):
  2. def inner(y):
  3. nonlocal x
  4. x += y
  5. return x
  6. return inner
  7. if __name__ == '__main__':
  8. demo = outer(5)
  9. print(demo(1))
  10. print(demo(2))
  11. # 很具有迷惑性;可以感知到 每次使用inner 函数 都是同一个 也就是说 都是x

变量的生命周期

在Python 中变量的生命周期按照:L>E>G>B来排序,有四种作用域:

  • L(Local):最内层,包含局部变量,比如一个函数/方法内部。
  • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
  • G(Global):当前脚本的最外层,比如当前模块的全局变量。
  • B(Built-in): 包含了内建的变量/关键字等。,最后被搜索

变量能够影响到程序征文区域 就是 变量的作用域

命名空间

  1. PI = 3.14
  2. def circle_area(r):
  3. return PI * r ** 2
  4. class Dog(object):
  5. def __init__(self, name):
  6. self.name = name
  7. def yelp(self):
  8. print('woof, i am', self.name)

以这个程序为例,代码中出现的每个变量的作用域分别是什么?程序中总共涉及几个名字空间?
变量 PI 全局变量
self.name 局部私有变量
_函数 _circle_area
类 Dog
——
在Python中 变量只是一个与实际对象绑定起来的名字。变量定义的本质就是建立名字与对象的约束关系

  • 模块导入
  • 函数 / 类 定义
  • as 关键字