9.4 定义一个带参数的装饰器
问题
你想定义一个可以接受参数的装饰器
解决方案
from functools import wraps
import logging
def logged(level, name=None, message=None):
"""
Add logging to a function. level is the logging
level, name is the logger name, and message is the
log message. If name and message aren't specified,
they default to the function's module and name.
"""
def decorate(func):
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
return decorate
# Example use
@logged(logging.DEBUG)
def add(x, y):
return x + y
@logged(logging.CRITICAL, 'example')
def spam():
print('Spam!')
最外层的函数 logged()
接受参数并将它们作用在内部的装饰器函数上面。 内层的函数 decorate()
接受一个函数作为参数,然后在函数上面放置一个包装器。
讨论
如果你有下面这个代码:
@decorator(x, y, z)
def func(a, b):
pass
装饰器处理过程跟下面的调用是等效的;
def func(a, b):
pass
func = decorator(x, y, z)(func)
Last updated
Was this helpful?