一.闭包
如果一个内嵌函数中引用了外部函数中的变量(非全局变量)。那么该内嵌函数称之为闭包
也就是将组成函数的语句和这些语句的执行环境打包在一起时,得到的对象
闭包满足的三个条件:
1.必须是内嵌函数
2.外层函数返回值是内嵌函数
3.内嵌函数引用外层函数变量
def Funx(x): def Funy(y): return x*y def Funz(z): return x*z return Funy,Funz y,z=Funx(5) #接收两个内嵌函数 print(y(2),z(3)) #分别调用
闭包:Python解析变量的LEGB法则,Local>Enclosing>Global>Bulitin ,在任何一层找到以后结束查找
Local 代表本地变量即内嵌函数内变量,
Enclosing 代表外层函数变量,如果是嵌套外层,则由内向外一直查找
Global 全局变量,即查找当前模块的变量
Bulitin 内置模块的预定义变量中查找
下面来一个例子帮助了解:
#foo.py filename="foo.py" def call_func(f): return f()
import foo #导入foo.py模块 filename="func.py" def show_name(): print(filename) call_func(show_name) #输出func.py
原因:由于闭包是封存上下文环境,所以call_func(show_name)会使用内嵌函数show_name的上下文
用LEGB法则解释:show_name函数和其外部里没有filename变量,就去当前模块func.py中查找该变量
二.装饰器&语法糖
装饰器是闭包的应用,在不修改原函数代码的情况下,对函数包装,为函数添加功能
def gd(fun): def wrapper(): return fun()+'我吃火锅,你吃火锅底料\t' return wrapper def kt(fun): def wrapper(): return fun()+'我吹空调,你吹空调外机\t' return wrapper @gd @kt def test(): return '我吃冰棍,你吃冰棍棒棒\t' # 相当于gd(kt(test)()) print(test())总结:闭包是典型的惰性赋值,外层函数局部变量不会丢失,会被封装到内嵌函数的环境中