场景:想写一个装饰器来包装一个函数,并且允许用户提供参数在运行时控制装饰器行为。
from functools import wraps, partial
import logging
def attach_wrapper(obj, func=None):
"""
如果需要减少某个函数的参数个数,可以使用 functools.partial() 。
partial() 函数允许给一个或多个参数设置固定的值,减少接下来被调用时的参数个数
"""
if func is None:
return partial(attach_wrapper, obj)
setattr(obj, func.__name__, func)
return func
def logged(level, name=None):
"""
Add logging to a function. level is the logging
level, name is the logger name. If name aren't
specified, they default to the function's module and name.
"""
def decorate(func):
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log_name = name if name else func.__module__
log = logging.getLogger(log_name)
@wraps(func)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
log.log(level, result)
return result
@attach_wrapper(wrapper)
def set_level(new_level):
nonlocal level
level = new_level
@attach_wrapper(wrapper)
def get_level():
return level
# wrapper.get_level = lambda: level
return wrapper
return decorate
@logged(logging.DEBUG)
def add(x, y):
return x + y
if __name__ == '__main__':
add(3, 2)
add.set_level(logging.INFO)
add(5, 5)
print(add.get_level())
2019-02-19 16:29:22,195 - __main__ - DEBUG - 5
2019-02-19 16:29:22,195 - __main__ - INFO - 10
20
网友评论