想编写一个装饰器,该装饰器可以不带参数(如@decorator)使用,也可以带可选参数(如@decorator(x,y,z))使用。 但是,由于简单修饰符和带有参数的修饰符之间的调用约定不同,因此似乎没有直接的方法。
以下示例解决了这种编程一致性问题:
from functools import wraps, partial
import logging
def logged(func=None, *, level=logging.DEBUG, name=None, message=None):
if func is None:
return partial(logged, level=level, name=name, message=message)
logname = name if name else func.__module__
log = logging.getLogger(logname)
logmsg = message if message else func.__name__
@wraps(func)
def wrapper(*args, **kwargs):
log.log(level, logmsg)
return func(*args, **kwargs)
return wrapper
# Example use
@logged
def add(x, y):
return x + y
@logged(level=logging.CRITICAL, name='example')
def spam():
print('Spam!')