装饰器
普通装饰器
import time
from functools import wraps
def timethis(func):
"""
这是一种计时装饰器
"""
@wraps(func) # 它可以用来保存函数的元数据,比如函数名, 文档字符串, 函数注解以及调用签名等, 所以建议一直保留
def wrapper(*args, **kwargs):
strart = time.time()
result = func(*args, **kwargs)
end = time.time()
print(func.__name__, end-strart)
return result
return wrapper
@timethis
def countdown(n):
"""
计数操作
"""
while n > 0:
n -= 1
# 使用样例
countdown(10000)
# countdown 0.00299072265625
countdown(1000000)
# countdown 0.17353367805480957
countdown.__name__
# countdown
# 将`@wraps(func)`注释掉后再执行结果如下:
coundown.__name__
# wrapper
可接受参数的装饰器
import logging
from functools import wraps, partial
def attach_wrapper(obj,func=None):
if func is None:
return partial(attach_wrapper, obj)
setattr(obj, func.__name__, func)
return func
def logged(level, name=None, message=None):
"""
add logging to a function, level is logging level, name is the logger name, and message is the log message,
if name and message is 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)
@attach_wrapper(wrapper)
def set_level(newlevel):
nonlocal level
level = newlevel
@attach_wrapper(wrapper)
def set_message(newmsg):
nonlocal logmsg
logmsg = newmsg
return wrapper
return decorate
未完待续…