Python装饰器
- 装饰器定义
- 装饰器的用途
- 内部函数带参装饰器
- 装饰器本身带参数
- 多层装饰器
装饰器定义
- 装饰器的作用就是用一个新函数封装旧函数(是旧函数代码不变的情况下增加功能)然后会返回一个新函数,新函数就叫做装饰器。
- 一般为了简化装饰器会用语法糖@新函数来简化。
- 装饰器是满足闭包条件的。
装饰器的用途
- 当一个函数在很多地方调用,其中某些地方需要扩充该函数的功能,但有的地方不需要,这时候,可以加装饰器,使得需要扩充该函数功能的地方满足扩充需求。
# 并未改变原函数内容,重新定义了新的函数,扩充了原函数的内容,但是需要在扩充功能的调用处都更换函数名。
def food():
print("rice, simple diet.")
def delicious_food(func):
func()
print("rice, vegetables and meat, delicious meal.")
delicious_food(food)
result:
rice, simple diet.
rice, vegetables and meat, delicious meal.
# 并未改变原函数内容,重新定义了新的函数,扩充了原函数的内容,但是需要在扩充功能的调用处都更换函数名。
def food():
print("rice, simple diet.")
def delicious_food(func):
func()
print("rice, vegetables and meat, delicious meal.")
delicious_food(food)
result:
rice, simple diet.
rice, vegetables and meat, delicious meal.
"""当看到@delicious_food时,这句话会做以下2个动作:
1.执行delicious_food函数。
2.将其返回值wrapper送给装饰的函数名,即food。
这样在调用原函数food()的时候,就会执行wrapper函数了,实现了功能的扩展。
"""
def delicious_food(func):
print("decorate funtion")
def wrapper():
print("inner function")
func()
print("rice, vegetables and meat, delicious meal.")
return wrapper
@delicious_food
def food():
print("rice, simple diet.")
print(food)
food()
result:
decorate funtion
.wrapper at 0x7f643a2c0f28>
inner function
rice, simple diet.
rice, vegetables and meat, delicious meal.
内部函数带参装饰器
# 内部函数带参可以为可变参数,增强其通用性。
# @decorate之后,food指向wrapper,所以wrapper和food的参数对应,但是后面的func()对应原food,所以要和food()的参数对应。
def decorate(func):
print("decorate funtion")
def wrapper(*args):
print("inner function")
func(*args)
print(func)
print("rice, vegetables and meat, delicious meal.",
"********",*args)
return wrapper
@decorate
def food(n):
print("rice, simple diet.","---------", n)
@decorate
def food2(m,n,t):
print("rice, simple diet.","---------", m,n,t)
food(10)
food2("noodles", 100, 88)
装饰器本身带参数
- 需要有三层函数定义。
- 第一层接收装饰器的参数,第二层接收函数,第三层接收函数的参数及调用被装饰的函数。
def outer(a): # 接收装饰器的参数
print(f"parameter is {a}")
def decorate(func): # 接收函数
print("decorate funtion")
def wrapper(*args): # 接收函数的参数及调用被装饰的函数
print("inner function")
func(*args)
print("rice, vegetables and meat, delicious meal.",
"********",*args)
return wrapper # 返回第三层函数地址
return decorate # 返回第二层函数地址
@outer(10)
def food(n):
print("rice, simple diet.","---------", n)
print("&&&", food)
food(10)
result:
parameter is 10
decorate funtion
&&& .decorate..wrapper at 0x7fb3e104dea0>
inner function
rice, simple diet. --------- 10
rice, vegetables and meat, delicious meal. ******** 10
多层装饰器
- 多层装饰器首先执行最靠近函数的装饰器,然后将这个装饰器返回的函数地址给外层的装饰器。
"""
1. 看到@decorate1,先去执行decorate1函数,food原函数作为参数传给decorate1的func,返回decorate1.wrapper给food。
2. 看到@decorate2,food所指向的decorate1.wrapper作为参数传给decorate2的func,返回decorate2.wrapper给food。
3. 当调用food()时,此时food所指向的是decorate2.wrapper,所以去执行它,而decorate2.wrapper中调用的func()函数,是decorate1.wrapper,而转去执行decorate1.wrapper。
4. decorate1.wrapper中的func是原函数food,所以去执行food函数。
"""
def decorate1(func):
print("decorate1",func)
def wrapper():
print("decorate1 inner")
func()
print("decorate1, rice, vegetables")
return wrapper
def decorate2(func):
print("decorate2",func)
def wrapper():
print("decorate2 inner")
func()
print("decorate1, rice, vegetables, meat, eggs")
return wrapper
@decorate2
@decorate1
def food():
print("rice, simple diet.","---------")
print("&&&", food)
food()
result:
decorate1
decorate2 .wrapper at 0x7ffaeb414ea0>
&&& .wrapper at 0x7ffaeb42b620>
decorate2 inner
decorate1 inner
rice, simple diet. ---------
decorate1, rice, vegetables
decorate1, rice, vegetables, meat, eggs