THU.装饰器
装饰器
- 什么是装饰器
- 器指的是工具,可以定义成函数
- 装饰指的是为其他事物添加额外的东西点缀
- 装饰器指的是定义一个函数,该函数是用来为其它函数添加额外的功能
- 为何要用装饰器
- 开放封闭原则
- 开放 – 拓展功能是开放的
- 封闭 – 对修改源代码是封闭的
- 装饰器本质是装饰源代码,是为了在不修改被装饰对象源代码以及调用方式的前提下,为被装饰对象拓展功能
- 开放封闭原则
- 装饰器的语法糖
import time
from functools import wraps
def delete_t(mistiming):
def fxx(*args, **kwargs):
start_t = time.time()
result = mistiming(*args, **kwargs)
stop_t = time.time()
print(stop_t - start_t)
return result
return fxx
@delete_t # foo = delete_t(foo的内存地址)
def foo(x):
time.sleep(3)
print('Welcome to foo %s' % x)
return 'Nice'
res = foo('Saber')
print(res)
语法糖将其正下方的函数当做参数传入装饰器,即@将被装饰对象的内存地址当做参数传入装饰器,并赋值给源内存地址的变量名
- 使用方法
- 无参装饰器
import time # 模块可以按需求更换
def outter(func):
def wrapper(*args, **kwargs):
res = func(*args,**kwargs)
retrun res
return func
@outter
def index(x):
print(x)
time.sleep(2)
return 返回值
result = index(a)
print(result)
- 有参装饰器
# 有参装饰器模板
def outer(x, y):
def deco(func):
def wrapper(*args, **kwargs):
print(x, y)
res = func(*args, **kwargs)
return res
return wrapper
return deco
@outter(111, 22)
def index():
print('index')
index()
- 由于语法糖@的限制,无参装饰器的参数个数是固定的,无法增加或减少,并且该参数只用来接收被装饰对象的内存地址,因此需要再进行一次装饰操作,来增加装饰器的参数,即有参装饰器
- 叠加多个装饰器
def deco1(func1): # func1 = wrapper2的内存地址
def wrapper1(*args, **kwargs):
print('===>运行wrapper1')
res1 = func1(*args, **kwargs)
return res1
return wrapper1
def deco2(func2): # func2 = wrapper3的内存地址
def wrapper2(*args, **kwargs):
print('===>运行wrapper2')
res2 = func2(*args, **kwargs)
return res2
return wrapper2
def deco3(func3): # func3 = index的内存地址
def wrapper3(*args, **kwargs):
print('===>运行wrapper3')
res3 = func3(*args, **kwargs)
return res3
return wrapper3
# index = wrapper1的内存地址
@deco1 # deco1(wrapper2的内存地址) -> wrapper1的内存地址
@deco2 # deco2(wrapper3的内存地址) -> wrapper2的内存地址
@deco3 # deco3(index的内存地址) -> wrapper3的内存地址
def index():
print('from index')
return 123
res = index() # wrapper1()
print(res)
- 自上而下运行,自下而上加载