为什么要使用?
使用装饰器使代码变得整洁,并且能解决硬编码问题,使用起来也很方便,但是理解起来相对没那么容易,因此写下这篇文章加深理解。下面以记录日志的功能作为装饰器的讲解:
原始硬编码版
下面的logit作为装饰器,但是它只能装饰有两个参数的函数,因此是硬编码的。
def logit(func):
def decorator(a, b):
print("func %s is calling " % func.__name__)
return func(a, b)
return decorator
@logit()
def my_add(a, b):
return a+b
my_add(1, 49)
可变参数版
使用*args, **kwargs将上述的硬编码去除,使得装饰器能装饰不同的函数
def logit(func):
def decorator(*args, **kwargs):
print("func %s is calling " % func.__name__)
return func(*args)
return decorator
wraps通用版
输出my_add.name发现函数的名称改变了,不是我们想要的my_add,因此使用wraps改造
print(my_add.__name__)
from functools import wraps
def logit(func):
@wraps(func)
def decorator(*args, **kwargs):
print("func %s is calling " % func.__name__)
return func(*args)
return decorator
自定义参数版
有时候需要向装饰器来传递参数,例如不同的函数需要不同的日志文件时:
def logit(log_name="add.log"):
def decorator(func)
@wraps(func)
def wrapper(*args, **kwargs):
log_str = "func %s is calling " % func.__name__
print(log_str)
with open(log_name, "a") as log_file:
log_file.write(log_str)
return func(*args)
return wrapper
return decorator
网友评论