装饰器:在不修改被装饰器对象源代码以及调用方式的前提下为被装饰对象添加新功能
源代码:
import time
def index(x, y):
time.sleep(3)
print('index %s %s' % (x, y))
index(1111, 2222)
添加需求,增加起始时间,算出间隔时间
方式一:
缺点:没有修改被装饰对象的调用方式,但是修改了源代码
import time
def index(x, y):
start = time.time()
time.sleep(3)
print('index %s %s' % (x, y))
stop = time.time()
print(stop - start)
index(1111, 2222)
方式二:
缺点:没有修改被装饰对象的调用方式 ,也没有修改源代码,加上了新功能,但是代码冗余
import time
def index(x, y):
time.sleep(3)
print(f'index {x} {y}')
start = time.time()
index(1111, 2222)
stop = time.time()
print(stop - start)
start = time.time()
index(1111, 2222)
stop = time.time()
print(stop - start)
方式三:
缺点:虽然解决了方式二代码冗余问题,但是带来了一个新问题即函数的调用方式改变了
import time
def index(x, y):
time.sleep(3)
print('index {} {}'.format(x, y))
def wrapper():
start = time.time()
index(1111, 2222)
stop = time.time()
print(stop - start)
wrapper()
方式四:
优点:将index的参数写活了,不受参数个数限制
import time
def index(x, y, z):
time.sleep(3)
print(f'index {x} {y} {z}')
def wrapper(*args, **kwargs):
start = time.time()
index(*args, **kwargs) # index(1, z=3, y=2)
stop = time.time()
print(stop - start)
wrapper(1, 2, 3)
wrapper(1, z=3, y=2)
方式五:
优点:在方式四的基础上把装饰器对象写活了,在原来只能装饰index
import time
def index(x, y, z):
time.sleep(3)
print(f'index {x} {y} {z}')
def home(a):
time.sleep(1)
print(f'这是一个home函数,它的参数是:{a} ')
def outter(func):
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
stop = time.time()
print(stop - start)
return wrapper
index = outter(index)
home = outter(home)
index(1, 2, 3)
home('winnie')
方式六:
优点:将wrapper做的跟被装饰对象一模一样,以假乱真,不改变函数的调用方式
import time
def index(x, y, z):
time.sleep(3)
print(f'index {x} {y} {z}')
def home(a):
time.sleep(1)
print(f'这是一个home函数,它的参数是:{a} ')
def outter(func):
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
stop = time.time()
print(stop - start)
return wrapper
index = outter(index) # index这个名字指向的是wrapper函数的内存地址
home = outter(home) # index这个名字指向的是wrapper函数的内存地址
index(1, 2, 3)
home('winnie')
方式七:
优点:语法糖
import time
def outter(func):
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
stop = time.time()
print(stop - start)
return wrapper
# 在被装饰对象正上方的单独一行写@装饰器名字
@outter # 相当于 index=outter(index)
def index(x, y, z):
time.sleep(3)
print(f'index {x} {y} {z}')
@outter # 相当于 home=outter(home)
def home(a):
time.sleep(1)
print(f'这是一个home函数,它的参数是:{a} ')
index(1, 2, 3)
home('winnie')