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