装饰器
1 开放封闭原则:对扩展开放,对修改(修改源代码和调用方式)是封闭的
2 什么是装饰器:装饰器本质是任意可调用对象,被装饰器对象也可以是任意可调用对象
装饰器遵循的原则:不修改被装饰对象的源代码和调用方式
3 定义装饰器
def 外部函数(func):
def 内部函数(*args,**kwargs):
pass
return 内部函数
4 装饰器的语法:@
1 写在被装饰对象的正上方单独一行
2 可以叠加多个,
定义阶段外部函数的执行顺序是自下而上
调用阶段内部函数的执行顺序是自上而下
import time
def timmer(fun):
def wrapper(*args, **kwargs):
start = time.time()
fun(*args, **kwargs)
stop = time.time()
res = stop - start
print("Time:",res)
return wrapper
@timmer
def main():
print("Lets start..")
main()
@timmer #index=timmer(index)
def index():
pass
主要流程:
从上向下解释,遇到函数定义timmer,跳过,
接着跳转到@timmer,它装饰main函数,将main函数当作
参数传给timmer,接着遇到wrapper函数定义,跳过,转到return wrapper,这些都走完了,走到mian()函数,紧接着跳转到
wrapper,开始执行wrapper函数,直到执行到fun,此时fun即
main()函数,然后打印lets start…,main函数执行完了,接着执行stop 这一句,然后执行后面的语句, 这里的@timmer的作用
实际是timmer(main)然后重新对main函数赋值,再次指向main
functools 保留元数据
def wrapper(f):
"""
This is wrapper
"""
def inner(*args, **kwargs):
"""
This is inner
"""
result = f(*args, **kwargs)
return result
return inner
@wrapper
def be_decorated():
"""
This is the function be decorated
"""
print('function be decorated')
return
print(be_decorated.__name__)
print(be_decorated.__doc__)
输出结果:
inner
This is inner
给inner加上装饰器:@functools.wrap(f)
import functools
def wrapper(f):
"""
This is wrapper
"""
@functools.wraps(f)
def inner(*args, **kwargs):
"""
This is inner
"""
result = f(*args, **kwargs)
return result
return inner
@wrapper
def be_decorated():
"""
This is the function be decorated
"""
print('function be decorated')
return
print(be_decorated.__name__)
print(be_decorated.__doc__)
输出结果:
be_decorated
This is the function be decorated
可以看到它保留了be_decorated函数的元数据