一、在函数上添加包装器
import time
from functools import wraps
def timethis(func):
'''
decorator that reports the execution time.
'''
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(func.__name__, end-start)
return result
return wrapper
@timethis
def countdown(n):
while n > 0:
n = n-1
使用内置装饰器
1.wraps保留函数元信息,能通过wrapped属性直接访问被包装函数,在底层访问到函数签名等信息。
2.property获取属性
3.setter和getter
4.classmethod类方法 staticmethod 静态方法
class Student(object):
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if value is not None:
self._name = value
@classmethod
def fun1(cls):
pass
@staticmethod
def fun2():
pass
二、带参数的装饰器
from functools import wraps
import logging
def logged(level, name=None, message=None):
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
@logged(logging.DEBUG)
def add(x, y):
return x+y
@logged(logging.CRITICAL, 'example')
def spam():
print('spam')
三、可自定义属性的装饰器
使用nonlocal
from functools import partial, wraps
import logging
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):
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 message
message = newmsg
return wrapper
return decorate
使用例子