1.初識裝飾器
裝飾器:具有特定功能的一個函數或類(類裝飾器以後會講),大多數情況下是一個函數,裝飾器是閉包的一種應用。
作用:不改變原來函數的代碼和調用方式,額外增加新的功能
軟件開發有一個開放封閉原則:
- 開放:對於拓展功能是開放的
- 封閉:對於修改源代碼是封閉的
裝飾器將這個原則體現的淋漓盡致。
2.裝飾器的使用
1.裝飾器的模板:
def outer(func):
def inner(*args,**kwargs):
...... 函數執行前的操作
ret = func()
...... 函數執行後的操作
return ret
return inner
2.使用裝飾器
裝飾器的使用語法:
@裝飾器名
def func():
xxx
實例代碼:
def wrapper(func):
def inner(*args,**kwargs):
print("start")
ret = func()
print("end")
return ret
return inner
def func():
print("hhh")
給func函數加裝飾器wrapper
@wrapper
def func():
print("hhh")
func()
結果如下:
3.爲什麼裝飾器的參數不能動?
裝飾器外部函數和內嵌函數的參數都不能動
def wrapper(func):
def inner(*args,**kwargs):
print("start")
ret = func()
print("end")
return ret
return inner
@wrapper
def func():
print("hhh")
外部函數的參數不能動:因爲語法糖的限制@wrapper=wrapper(func)
內部函數的參數不能動:因爲加了裝飾器後要保證原函數的調用方式不能動
3.裝飾器進階
1.裝飾器的組合使用
可以給一個函數加多個裝飾器
記住:從下往上裝飾,從上往下執行
實例代碼:
def wrapper1(func):
def inner1(*args,**kwargs):
print("wrapper1前")
ret = func()
print("wrapper1後")
return ret
return inner1
def wrapper2(func):
def inner2(*args,**kwargs):
print("wrapper2前")
ret = func()
print("wrapper2後")
return ret
return inner2
@wrapper2
@wrapper1
def func():
print(1)
func()
結果如下:
2.裝飾器的修復技術
爲了加裝飾器後不修改原函數的屬性,需要使用裝飾器的修復技術。
如果不加裝飾器的修復技術,通過被裝飾函數名拿到的函數屬性是內嵌函數的屬性,如果加了通過原函數名拿到的函數屬性還是原函數的屬性。
如果不加裝飾器的修復技術
def wrapper(func):
def inner(*args,**kwargs):
ret = func(*args,**kwargs)
return ret
return inner
@wrapper
def index():
pass
print(index.__name__) 結果爲inner
如果加了裝飾器的修復技術
from functools import wraps
def wrapper(func):
def inner(*args,**kwargs):
ret = func(*args,**kwargs)
return ret
return inner
@wrapper
def index():
pass
print(index.__name__) 結果爲:index
3.有參裝飾器
爲了給裝飾器傳額外的參數。在原來裝飾器的基礎上再套一層。
有參裝飾器的模板和使用
模板:
def 有參裝飾器(*args,**kwargs):
def outer(func):
def inner(*args,**kwargs):
......函數執行前的操作
ret = func()
return ret
......函數執行後的操作
return inner
return outer
使用:
@有參裝飾器(*args,**kwargs) #@有參裝飾器(*args,**kwargs)==@outer
def func(*args,**kwargs):
...
有參裝飾器的使用
def outer(x):
def wrapper(func):
def inner(*args,**kwargs):
print("這是第{}次調用".format(x))
ret = func(*args,**kwargs)
return ret
return inner
return wrapper
@outer(5)
def index():
print("index")
index()