关于Python闭包(Closures)的那点事
2019-04-29 本文已影响0人
长风破浪小武哥
什么是闭包?
类比一下对象,对象是封装了方法的数据,闭包是封装了数据的方法。
举个栗子
def outer(x):
# 1
def inner(y):
print(x)
return x+y
return inner # 2
g = outer(5) # 3
print(g.__closure__) # 4
print(g(6)) # 5
请问上面的代码能够顺利执行吗?
上面的代码执行没有任何问题。
但我相信第一次接触闭包的同学肯定会对x的作用域有疑问,在这段代码中x是一个outer函数内部的
局部变量, 生命周期应该从入参到 #1到 #2才对, 所以当#3执行完后x已经被释放了, 当执行#5时
innner函数被触发,但此时应该访问不到x,应该会抛出一个x未定义的异常才对,但是这一些都没有发生,
inner函数依旧正常执行,打印了x。
输出结果:
(<cell at 0x7efd66558108: int object at 0xa67b40>,)
5
11
分析一下
Python支持一种特性叫做函数闭包(function closures):在非全局(global)作用域中定义inner函数(即嵌套函数)时,会记录下它的嵌套函数namespaces(嵌套函数作用域的locals),可以称作:定义时状态,可以通过closure 这个属性来获得inner函数的外层嵌套函数的namespaces。(如上例中#5,打印了func_closure ,里面保存了一个int对象,这个int对象就是x)
在这个例子中,我们能看到闭包实际上是记录了外层嵌套函数作用域中的local变量
闭包的应用场景
- 替换硬编码常量
- 终结全局
- 提供一致的功能签名
- 实现面向对象