闭包
首先需要明确:函数名的本质是变量名,可以被赋值,给别的变量赋值,做参数传递,做返回值
闭包:一个嵌套函数,外部函数返回内部函数引用,内部函数使用外部函数的局部自由变量。
deftravel():
animal="猴子"defanimals():print(animal)return animalreturn animals
fn= travel()
ani= fn()# 函数外部访问到了函数的局部变量
闭包的作用:
1.让一个变量常驻内存
2.保护变量不被修改
装饰器
装饰器是通过闭包的方式实现的。
– 外部函数接收一个函数作为函数的参数变量,内部函数中执行这个函数;
– 内部函数接收需要的参数给执行的函数,返回执行结果;
– 内部函数中可以添加额外的功能代码;
– 外函数将内函数返回
- 通用装饰器的写法
defwrapper(fn):definner(*args,**kwargs):print("买长颈鹿吃的食物")
ret= fn(*args,**kwargs)print("收拾垃圾")return retreturn inner@wrapper# 在不改变原来函数的基础上,给函数增加新的功能 等于fn = wrapper(travel)deftravel(age, name):print(f"{age}岁以上的{name}给长颈鹿喂食")return"真是开心的一天"
ret= travel(8,"小孩")# 实际上执行的是inner函数print(ret)# #相当于@wrapper# fn = wrapper(travel)# fn(8, "小孩")
- 高阶装饰器:同一个函数被多个装饰器装饰
defwrapper1(fn):definner(*args,**kwargs):print("wrapper1-before")
ret= fn(*args,**kwargs)print("wrapper1-after")return retreturn innerdefwrapper2(fn):definner(*args,**kwargs):print("wrapper2-before")
ret= fn(*args,**kwargs)print("wrapper2-after")return retreturn innerdefwrapper3(fn):definner(*args,**kwargs):print("wrapper3-before")
ret= fn(*args,**kwargs)print("wrapper3-after")return retreturn inner@wrapper3@wrapper2@wrapper1# 执行时按照就近原则deftarget():print("我是目标执行函数")
target()
- 带有参数的装饰器
defwrapper_other(name):defwrapper(fn):definner(*args,**kwargs):print(f"{name}爱吃的食物")
ret= fn(*args,**kwargs)print(f"打扫{name}吃完的垃圾")return retreturn innerreturn wrapper# 先执行wrapper_other函数调用,返回wrapper装饰器和前面的@组合成语法糖@wrapper@wrapper_other("猴子")deftravel():print("我是猴子")
travel()