函数装饰器
import time
def decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
return wrapper
@decorator
def fun():
time.sleep(0.8)
fun() # 函数调用# 输出:0.800644397735595
类方法的函数装饰器
类方法的函数装饰器和函数的函数装饰器类似。
import time
def decorator(func):
def wrapper(me_instance):
start_time = time.time()
func(me_instance)
end_time = time.time()
print(end_time - start_time)
return wrapper
class Method(object):
@decorator
def func(self):
time.sleep(0.8)
p1 = Method()
p1.func() # 函数调用
类装饰器
- 这里有注意的是:call()是一个特殊方法,它可将一个类实例变成一个可调用对象。
- 要使用类装饰器必须实现类中的__call__()方法,就相当于将实例变成了一个方法。
class Decorator(object):
def __init__(self, f):
self.f = f
def __call__(self):
print("decorator start")
self.f()
print("decorator end")
@Decorator
def func():
print("func")
func()
print('-'*20)
p = Decorator(func) # p是类Decorator的一个实例
p() # 实现了__call__()方法后,p可以被调用
装饰器链
由近至远
def makebold(f):
return lambda: "<b>"+f()+"</b>"
def makeitalic(f):
return lambda: "<i>"+f()+"</i>"
@makebold
@makeitalic
def say():
return "hello"
print(say()) #bold(italic(say))
python装饰器库–functools
import time
def decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
return wrapper
@decorator
def func():
time.sleep(1)
func() # 函数调用
print(func.__name__)
#-------------------------------
from functools import wraps
def decorator2(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
return wrapper
@decorator2
def func2():
time.sleep(2)
func2() # 函数调用
print(func2.__name__)
显然第一个函数fun.__ name __输出wrapper,这表示被装饰函数自身的信息丢失了!怎么才能避免这种问题的发生呢?
如上述代码中的decorater2,即,可以借助functools.wraps()函数实现。