裝飾器
裝飾器的本質:一個閉包函數
裝飾器的功能:在不修改原函數及其調用方式的情況下對原函數功能進行擴展
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