装饰器的多种实现方式
一、基于函数实现
1、嵌套函数
代码实现:
1 from functools import wraps 2 3 4 def decorator(param): 5 def wrapper(func): 6 @wraps(func) 7 def verify(*args, **kwargs): 8 if param == 'g': 9 print(">>开始执行:{}".format(func.__name__)) 10 func(*args, **kwargs) 11 12 return verify 13 14 return wrapper 15 16 17 @decorator(param='g') 18 def func(): 19 print(">>生活如夏日流水般缓缓前进,我们不要焦急")
上面这种嵌套函数看着着实费劲,所以下面介绍另外两种方式,相对比较快捷易懂
2、三方库decorator
代码实现
1 from decorator import decorator 2 3 @decorator 4 def decorator(func, param=None, *args, **kwargs): 5 if param == "g": 6 print(">>开始执行:{}".format(func.__name__)) 7 return func(*args, **kwargs) 8 9 10 @decorator(param='g') 11 def func(): 12 print(">>生活如夏日流水般缓缓前进,我们不要焦急")
3、三方库wrapt
代码实现
1 import wrapt 2 3 4 # 不带参数 5 @wrapt.decorator 6 def wrapper(func, instance, args, kwargs): # 函数签名不可写错 7 print(">>prepare") 8 return func(*args, **kwargs) 9 10 11 # 带参数 12 def test(name): 13 @wrapt.decorator 14 def wrapper(func, instance, args, kwargs): 15 if name == "g": 16 print(">>prepare") 17 else: 18 print(">>go...") 19 return func(*args, **kwargs) 20 21 return wrapper 22 23 24 @test(name="c") 25 def func(): 26 print(">execute") 27 28 29 if __name__ == '__main__': 30 func()
二、基于类实现
1、不带参数
构造器传入被装饰函数
代码实现
1 class Decorator: 2 def __init__(self, func): 3 self.func = func 4 5 def __call__(self, *args, **kwargs): 6 print(">>开始执行:{}".format(self.func.__name__)) 7 return self.func(*args, **kwargs) 8 9 10 @Decorator 11 def func(): 12 print(">>生活如夏日流水般缓缓前进,我们不要焦急")
2、带参数
构造器传入参数
代码实现
1 class Decorator: 2 def __init__(self, param): 3 self.argument = param 4 5 def __call__(self, func): 6 def wrapper(*args, **kwargs): 7 if self.argument == 'g': 8 print(">>开始执行:{}".format(func.__name__)) 9 return func(*args, **kwargs) 10 return wrapper 11 12 13 @Decorator(param="g") 14 def func(): 15 print(">>生活如夏日流水般缓缓前进,我们不要焦急")