1. 简单装饰器
import timedef timer(func): def wrapper(*args,**kwargs): t1 = time.time() func(*args,**kwargs) t2 = time.time() run_time = t2 - t1 print(run_time) return wrapper@timerdef foo(): time.sleep(3)#foo() # 3.0006301403045654foo = timer(foo) # 等同于使用timer装饰器foo() # 3.0006301403045654
2. 带参数的装饰器
import loggingdef log(level): def decorator(func): def wrapper(*args,**kwargs): if level == 'warn': logging.warn("%s is running" % func.__name__) return func(*args,**kwargs) return wrapper return decorator@log('warn')def foo(a='123'): print('the number is %s' %a)foo()the number is 123WARNING:root:foo is running
3. 类装饰器
import loggingdef log(level): def decorator(func): def wrapper(*args,**kwargs): if level == 'warn': logging.warn("%s is running" % func.__name__) return func(*args,**kwargs) return wrapper return decorator@log('warn')def foo(a='123'): print('the number is %s' %a)foo()the number is 123WARNING:root:foo is running
4. 类装饰器
import loggingdef log(level): def decorator(func): def wrapper(*args,**kwargs): if level == 'warn': logging.warn("%s is running" % func.__name__) return func(*args,**kwargs) return wrapper return decorator@log('warn')def foo(a='123'): print('the number is %s' %a)foo()the number is 123WARNING:root:foo is running
5. functools.wraps
#装饰器有个缺点,会改变原函数的元信息#functools.wraps本身也是装饰器,可把元信息拷贝到装饰器函数中,使元信息和原装饰器一致from functools import wrapsdef logged(func): @wraps(func) def with_logging(*args,**kwargs): print(func.__name__ + "was called") return func(*args,**kwargs) return with_logging@loggeddef f(x): """does soma math"""return x + x * xprint(f.__name__)print(f.__doc__)
6. 装饰器顺序
@a@b@cdef f(): pass# 等价于f = a(b(c(f)))