您好,登錄后才能下訂單哦!
裝飾器的概念
裝飾器是 Python 的一個(gè)重要部分。簡(jiǎn)單地說(shuō):就是用于拓展原來(lái)函數(shù)功能的一種函數(shù),目的是在不改變?cè)瘮?shù)名(或類(lèi)名)的情況下,給函數(shù)增加新的功能。
這個(gè)函數(shù)的特殊之處在于它的返回值也是一個(gè)函數(shù),這個(gè)函數(shù)是內(nèi)嵌 “原” 函數(shù)的函數(shù)。
將函數(shù)作為參數(shù)傳給另一個(gè)函數(shù)
def yanzheng():
return "--- 正在驗(yàn)證 ---"
def login(func):
print(func())
print("--- 正在登陸 ---")
login(yanzheng)
運(yùn)行結(jié)果:
--- 正在驗(yàn)證 ---
--- 正在登陸 ---
寫(xiě)代碼要遵循開(kāi)放封閉原則,雖然在這個(gè)原則是用的面向?qū)ο箝_(kāi)發(fā),但是也適用于函數(shù)式編程,簡(jiǎn)單來(lái)說(shuō),它規(guī)定已經(jīng)實(shí)現(xiàn)的功能代碼不允許被修改,但可以被擴(kuò)展,即:
封閉:已實(shí)現(xiàn)的功能代碼塊
開(kāi)放:對(duì)擴(kuò)展開(kāi)發(fā)
現(xiàn)在你已經(jīng)具備所有必需知識(shí),接下來(lái)進(jìn)一步學(xué)習(xí)什么是真正的裝飾器。
你的第一個(gè)裝飾器
def func_out(func):
def func_in():
print("--- 正在驗(yàn)證 ---")
func()
return func_in
@func_out
def login():
print("--- 正在登陸 ---")
login()
運(yùn)行結(jié)果:
--- 正在驗(yàn)證 ---
--- 正在登陸 ---
@函數(shù)名稱(chēng) 是 Python 的一種語(yǔ)法糖。簡(jiǎn)而言之,語(yǔ)法糖就是程序語(yǔ)言中提供[奇技淫巧]的一種手段和方式而已。 通過(guò)這類(lèi)方式編寫(xiě)出來(lái)的代碼,即好看又好用,好似糖一般的語(yǔ)法。固美其名曰:語(yǔ)法糖
裝飾器下面正好是個(gè)函數(shù),則默認(rèn)執(zhí)行:login = func_out(login)
裝飾器的流程圖
裝飾有返回值的函數(shù)
上面的案例,被裝飾的 login() 函數(shù)并沒(méi)有返回值,那么接下來(lái)咱們看看有返回值的函數(shù)如何裝飾。
首先,先看第一個(gè)案例:
def func_out(func):
def func_in():
print("--- 正在驗(yàn)證 ---")
func()
return func_in
@func_out
def login():
return "--- 正在登陸 ---"
result = login()
print(result)
運(yùn)行結(jié)果:
--- 正在驗(yàn)證 ---
None
思考一下,為什么我調(diào)用 login() 函數(shù),并且使用 result 變量來(lái)接收返回值,為什么結(jié)果是 None 呢?
如果想不明白,就看看第二個(gè)案例:
def func_out(func):
def func_in():
print("--- 正在驗(yàn)證 ---")
data = func()
return data
return func_in
@func_out
def login():
return "--- 正在登陸 ---"
result = login()
print(result)
運(yùn)行結(jié)果:
--- 正在驗(yàn)證 ---
--- 正在登陸 ---
大家仔細(xì)觀察代碼,這兩個(gè)案例有哪些不同?
發(fā)現(xiàn)了嗎?我在 func_in() 函數(shù)的里面多寫(xiě)了兩句代碼:
1、當(dāng)我們調(diào)用被裝飾的 login() 函數(shù)時(shí),實(shí)際執(zhí)行的是 func_in() 函數(shù)的代碼,此時(shí)會(huì)調(diào)用 print() 函數(shù)打印 "--- 正在驗(yàn)證 ---"。 鄭州人流醫(yī)院 http://rl.zyfuke.com/
2、代碼執(zhí)行到 data = func() 時(shí),會(huì)先執(zhí)行右側(cè)的 func() 函數(shù),而這個(gè)函數(shù)是原始的 login() 函數(shù),所以會(huì) return 返回一個(gè)值,此時(shí)這個(gè)值被等號(hào)左側(cè)的 data 變量接收。
3、代碼執(zhí)行到 return data,此時(shí)會(huì)將 data 值返回更上一層,而這個(gè)值被 result 變量接收。
4、最終打印 result 變量就輸出了原始 login() 函數(shù)的值。
在這里最需要注意的就是 return 返回?cái)?shù)據(jù),只能返回一層函數(shù),多層時(shí),就需要在上層同時(shí)使用 return。
裝飾有參數(shù)的函數(shù)
demo1:
def func_out(func):
def func_in():
func()
return func_in
def login(a):
prin
print(a)
login(10)
運(yùn)行結(jié)果:
10
demo2:
def func_out(func):
def func_in():
func()
return func_in
@func_out
def login(a):
print(a)
login(10)
運(yùn)行結(jié)果:
TypeError: func_in() takes 0 positional arguments but 1 was given
類(lèi)型錯(cuò)誤:func_in()接受0個(gè)位置參數(shù),但給出了1個(gè)
demo3:
def func_out(func):
def func_in(data):
func(data)
return func_in
@func_out
def login(a):
print(a)
login(10)
運(yùn)行結(jié)果:
10
demo4:
def func_out(func):
def func_in(*args,**kwargs):
func(*args,**kwargs)
return func_in
@func_out
def login(*args,**kwargs):
print(args)
print(kwargs)
login(10,20,c=1,b=2)
運(yùn)行結(jié)果:
(10, 20)
{'c': 1, 'b': 2}
總結(jié)
裝飾器函數(shù)只有一個(gè)參數(shù)就是被裝飾的函數(shù)的引用
裝飾器能夠?qū)⒁粋€(gè)函數(shù)的功能在不修改代碼的情況下進(jìn)行擴(kuò)展
在函數(shù)定義的上方@裝飾器函數(shù)名 即可直接使用裝飾器對(duì)下面的函數(shù)進(jìn)行裝飾
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。