原地址:https://zhuanlan.zhihu.com/p/65968462
import time
#装饰函数
def logger(func):
def wrapper(*args,**kw):
print("我要开始运行:{}函数了".format(func.__name__))
#真正执行的是这行
func(*args,**kw)
print("运行完成!")
return wrapper
@logger
def add(x,y):
print(x,'+',y,' = ',x+y)
def timer(func):
def wrapper(*args,**kw):
t1 = time.time()
#真正执行的地方
func(*args,**kw)
t2 = time.time()
#计算时长
costTime = t2 - t1
print("花费时间:",costTime)
return wrapper
@timer
def wantSleep(sleepTime):
time.sleep(sleepTime)
'''
带参数的装饰器
'''
def sayHello(country):
def wrapper(func):
def deco(*args,**kw):
if country == '中国':
print( '你好!')
elif country == 'american':
print( 'Hello!')
else:
return
#真正执行函数的地方
func(*args,**kw)
return deco
return wrapper
@sayHello('中国')
def chinese():
print('我是中国人!')
@sayHello('american')
def american():
print('I am american!')
'''
基于类实现的装饰器
必须实现__call__ 和 __init__两个内置函数
__call__:接受被装饰函数
__init__:实现装饰逻辑
'''
class logger():
def __init__(self,func):
self.func = func
def __call__(self,*args,**kw):
print(self.func.__name__,"() is running!")
return self.func(*args,**kw)
@logger
def say(something):
print("say ",something)
say('hello!')
'''
带参数的类装饰器
__init__:接受参数
__call__:接受被装饰函数,完成装饰逻辑
'''
class logger():
def __init__(self,level='INFO'):
self.level = level
def __call__(self,func):
def wrapper(*args,**kwargs):
print("[{level}]: the function {func}() is running..." \
.format(level=self.level, func=func.__name__))
func(*args,**kwargs)
return wrapper
@logger(level='WARNING')
def say(something):
print("say ",something)
say('hello!')
'''
返回的名字都是innerFunc
是因为执行wrapped 与执行wrapper(wrapped)是等价的
所以名字也是等价的
'''
def wrapper(func):
def innerFunc():
pass
return innerFunc
@wrapper
def wrapped():
pass
print(wrapper(wrapped).__name__,wrapped.__name__)
'''
解决这个问题,使用functools中的wraps装饰器,它的作用就是将
被装饰的函数wrapped的一些属性赋值给装饰器函数wrapper,最终让属性的显示更加符合我们的直觉
'''
from functools import wraps
def wrapper(func):
@wraps(func)
def innerFunc():
pass
return innerFunc
@wrapper
def wrapped():
pass
print(wrapped.__name__,wrapper(wrapped).__name__)