上一篇介绍过普通函数的装饰器的简单用法,如果被装饰的函数需要传入参数,那装饰器则不能使用。因为装饰器中返回的函数并不能接受参数。
一、带参数的功能函数
def decorator(fun):
def wrapper():
print('---start---')
fun()
print('----end---')
return wrapper
@decorator
def fun(a,b):
print(a+b)
fun(1,2)
运行结果:
TypeError: wrapper() takes 0 positional arguments but 2 were given
需要两个参数,则可以指定装饰器函数wrapper接受和原函数一样的参数:
def decorator(fun):
def wrapper(a,b):
print('---start---')
fun(a,b)
print('----end---')
return wrapper
@decorator
def fun(a, b):
print(a + b)
fun(1, 2)
运行结果:
---start---
3
----end---
现有如下函数fun1需要3个参数或者fun2不需要参数,需要用同一个装饰器去装饰,这时可以将装饰器中的参数设为不定长参数:
def decorator(fun):
def wrapper(*args, **kwargs):
print('---start---')
fun(*args,**kwargs)
print('----end---')
return wrapper
@decorator
def fun(a, b):
print(a + b)
@decorator
def fun1(a, b, c):
print(a + b + c)
@decorator
def fun2():
print("无参数")
运行结果:
fun(1,2)
---start---
3
----end---
————————————————————————————————————————————————————————
fun1(1,2,3)
---start---
7
----end---
————————————————————————————————————————————————————————
fun2()
---start---
无参数
----end---
当被装饰的函数有返回值时,由于在装饰器中的wrapper函数中没有返回fun3的调用结果,如下为None
二、功能函数有返回值
def decorator(fun):
def wrapper(*args, **kwargs):
print('---start---')
fun(*args, **kwargs)
print('----end---')
return wrapper
@decorator
def fun3():
return "我是fun3"
print(fun3())
运行结果:
---start---
----end---
None
这种情况则需要在wrapper中返回原功能函数的调用结果:
// An highlighted block
def decorator(fun):
def wrapper(*args, **kwargs):
print('---start---')
res = fun(*args, **kwargs)
print('----end---')
return res
return wrapper
@decorator
def fun3():
return "我是fun3"
print(fun3())
运行结果:
---start---
----end---
我是fun3
三、带参数的装饰器 当原函数需要装饰器来传入参数来进行某些操作时,如下使用前文中的装饰器运行: 参数2会做为fun传入,结果显而易见
def decorator(fun):
def wrapper(*args, **kwargs):
print('---start---')
res = fun(*args, **kwargs)
print('----end---')
return res
return wrapper
@decorator(2)
def fun4(a):
return a
print(fun4(1))
运行结果:
TypeError: 'int' object is not callable
这时需要在定义一层函数来接收装饰器的参数,并返回装饰器函数,如下:
def decorator(num):
def wrapper1(fun):
def wrapper(*args, **kwargs):
print("装饰器传入的参数:", num)
print('---start---')
res = fun(*args, **kwargs)
print('----end---')
return res
return wrapper
return wrapper1
@decorator(1)
def fun5(a):
return a
print(fun5(2))
运行结果:
装饰器传入的参数: 1
---start---
----end---
2
四、多层装饰器 当多个装饰器装饰一个功能函数时,来看下执行结果及顺序
def decorator(fun):
print("执行decorator")
def wrapper(*args, **kwargs):
print('---decorator_start---')
res = fun(*args, **kwargs)
print('---decorator_end---')
return res
return wrapper
def decorator1(fun):
print("执行decorator1")
def wrapper(*args, **kwargs):
print('---decorator1_start---')
res = fun(*args, **kwargs)
print('---decorator1_end---')
return res
return wrapper
@decorator1
@decorator
def fun():
print("功能函数")
fun()
运行结果:
执行decorator
执行decorator1
---decorator1_start---
---decorator_start---
功能函数
---decorator_end---
---decorator1_end---
|