装饰器的本质:一个闭包函数
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
import time
def func1():
print('in func1')
def timer(func): # 装饰器函数
def inner():
start = time.time()
func() # 被装饰的函数
print(time.time() - start)
return inner
func1 = timer(func1)
func1()
#-----------------------------------------------------------
# 语法糖
import time
def timer(func):
def inner():
start = time.time()
func()
print(time.time() - start)
return inner
@timer #==> func1 = timer(func1)
def func1():
print('in func1')
func1()
装饰器——带参数的装饰器
def timer(func):
def inner(a):
start = time.time()
func(a)
print(time.time() - start)
return inner
@timer
def func1(a):
print(a)
func1(1)
装饰器——成功hold住所有函数传参
import time
def timer(func):
def inner(*args,**kwargs):
start = time.time()
re = func(*args,**kwargs)
print(time.time() - start)
return re
return inner
@timer #==> func1 = timer(func1)
def func1(a,b):
print('in func1')
func1('aaaaaa','bbbbbb')
装饰器——带返回值的装饰器
import time
def timer(func):
def inner(*args,**kwargs):
start = time.time()
re = func(*args,**kwargs)
print(time.time() - start)
return re
return inner
@timer #==> func2 = timer(func2)
def func2(a):
print('in func2 and get a:%s'%(a))
return 'fun2 over'
func2('aaaaaa')
print(func2('aaaaaa')
查看函数信息的一些方法
def index():
'''这是一个主页信息'''
print('from index')
print(index.__doc__) #查看函数注释的方法
print(index.__name__) #查看函数名的方法
完美的装饰器
from functools import wraps
def deco(func):
@wraps(func) #加在最内层函数正上方
def wrapper(*args,**kwargs):
return func(*args,**kwargs)
return wrapper
@deco
def index():
'''哈哈哈哈'''
print('from index')
print(index.__doc__)
print(index.__name__)
装饰器固定模式
def wrapper(func):
def inner(*args,**kwargs):
'''写函数之前要做的'''
ret = func(*args,**kwargs)
'''写函数之后要做的'''
return ret
return inner
@wrapper
def func(*args):
print(args)
return 'func over'
ret = fuc()
开放封闭原则
对扩展是开放的 对修改是封闭的def warrper(func):
def inner(*args,**kwargs):
print('在被装饰器函数执行之前要做的事')
ret = func(*args,**kwargs)
print('在被装饰器函数执行之后要做的事')
return ret
return inner
@warrper # 等于 holiday = warrper(holiday)
def holiday(day):
print('全体放假%s天' %day)
return '好开心'
ret = holiday(3) # 等于inner(3)
print(ret)
带参数的装饰器
def outer(flag):
def timer(func):
def inner(*args,**kwargs):
if flag:
print('''执行函数之前要做的''')
re = func(*args,**kwargs)
if flag:
print('''执行函数之后要做的''')
return re
return inner
return timer
@outer(False)
def func():
print(111)
func()
import time
FLAG = True
def timmer_out(flag):
def timmer(func):
def inner(*args,**kwargs):
if flag:
start = time.time()
ret = func(*args,**kwargs)
end = time.time()
print(end-start)
return ret
else:
ret = func(*args,**kwargs)
return ret
return inner
return timmer
@timmer_out(FLAG) # 等于@timmer timmer = timmer_out(FLAG)
def wahaha():
time.sleep(1)
print('hahahahaha')
wahaha()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cTPaA6Ai-1582092534098)(D:\学习笔记\九月\1568686641493.png)]
多个装饰器装饰同一个函数
def wrapper1(func): # func --> f
def inner1():
print('wrapper1 ,before func')
func()
print('wrapper1 ,after func')
return inner1
def wrapper2(func): # func --> inner1
def inner2():
print('wrapper2 ,before func')
func()
print('wrapper2 ,after func')
return inner2
@wrapper2 # f = wrapper2(inner1) = inner2
@wrapper1 # f = wrapper1(f) = inner1
def f():
print('in f')
f()
# 执行结果
>>> wrapper2 ,before func
>>> wrapper1 ,before func
>>> in f
>>> wrapper1 ,after func
>>> wrapper2 ,after func