今天就跟大家聊聊有關(guān)Python中強(qiáng)大的裝飾器Decorators的工作原理,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
網(wǎng)站建設(shè)公司,為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì)及定制網(wǎng)站建設(shè)服務(wù),專(zhuān)注于企業(yè)網(wǎng)站制作,高端網(wǎng)頁(yè)制作,對(duì)成都餐廳設(shè)計(jì)等多個(gè)行業(yè)擁有豐富的網(wǎng)站建設(shè)經(jīng)驗(yàn)的網(wǎng)站建設(shè)公司。專(zhuān)業(yè)網(wǎng)站設(shè)計(jì),網(wǎng)站優(yōu)化推廣哪家好,專(zhuān)業(yè)網(wǎng)站推廣優(yōu)化,H5建站,響應(yīng)式網(wǎng)站。
這篇文章主要介紹 decorator(裝飾器),在開(kāi)始介紹 decorator 前,要先有一個(gè)觀念,就是在 python 中,函數(shù)是對(duì)象,可以將它們分配給變量和傳遞給其他函數(shù)并從其他函數(shù)返回,可以在其他函數(shù)中定義函數(shù),并且子功能可以捕獲父功能的本地狀態(tài)。
demo1.py
def f1():
print("f1")
def register(func):
func()
register(f1)
裝飾器就是站在這個(gè)基礎(chǔ)上去延伸出來(lái)的。接著來(lái)說(shuō)說(shuō)什麼時(shí)候要用裝飾器,裝飾器最主要的目的是在不破壞 function(函數(shù)) 或 class(類(lèi)) 的情況下,去擴(kuò)充目標(biāo) function 或 class 的功能。例如,logging、計(jì)算 function or class 執(zhí)行的時(shí)間、權(quán)限等等。
如果大家有興趣,可以再去查查 AOP ( Aspect Oriented Programming ),中文翻成 面向切面。
有了這個(gè)裝飾器,我們就可以將大量的程式碼抽出來(lái)( 與函數(shù)本身無(wú)關(guān)的部分 ),將這些 code 寫(xiě)到裝飾器中 ( 可以重復(fù)使用 ),程式碼也不會(huì)變得很亂。
說(shuō)穿了,就是在現(xiàn)在的功能上,可以加上額外的功能 ( 重點(diǎn)是不破壞原有的 code )。
舉個(gè)例子,今天我想要記錄 f1() 的 logging,我們可能這樣寫(xiě),
( 正常來(lái)說(shuō),應(yīng)該要使用 logging 這個(gè) module,但這邊簡(jiǎn)單用 print 代替就好 ????)
def f1():
print("f1")
print("logging - f1 is running")
f1()
這樣寫(xiě)看似沒(méi)有問(wèn)題,但如果你今天 f2() f3() f4() 都需要紀(jì)錄呢 ?
這樣要每一個(gè)都寫(xiě)一樣的 code ?
我們能不能把它抽出來(lái) ? 而這個(gè)東西,就是專(zhuān)門(mén)處理 logging 的,
答案當(dāng)然是可以的????
def my_logging(func):
print('logging - {} is running'.format(func.__name__))
func()
def f1():
print("f1")
my_logging(f1)
功能實(shí)現(xiàn)了,看似很美好,如果有其他的需要加上 logging,使用 my_logging(f2) 即可。但這方法其實(shí)有一些問(wèn)題,問(wèn)題點(diǎn)在每次都要呼叫 my_logging,而且也要將 f1 當(dāng)成參數(shù)傳遞,比較好的方法應(yīng)該是維持 f1 為主要業(yè)務(wù)邏輯,而不是像現(xiàn)在變成 my_logging 為主要業(yè)務(wù)邏輯,也就是說(shuō),現(xiàn)在的狀況破壞了原有代碼的結(jié)構(gòu)。所以更好的方法,就是使用裝飾器 ( 我們終于談到主角了????),來(lái)看一個(gè)簡(jiǎn)單的裝飾器。
def my_logging(func):
def wrapper():
print('logging - {} is running'.format(func.__name__))
func() # run func() Equivalent run f1()
return wrapper
def f1():
print("f1")
f1 = my_logging(f1) # Equivalent -> f1 = wrapper
f1() # Equivalent -> f1() = wrapper()
my_logging 就是一個(gè)裝飾器,把真正的業(yè)務(wù)邏輯 func 包在里面,看起來(lái)就像是 func 被 my_logging 裝飾了一樣,所以顧名思義,稱為裝飾器。在這個(gè)范例中,函數(shù)的進(jìn)入和退出時(shí),都可以加上東西,這種方式也稱為 AOP ( Aspect Oriented Programming )。接下來(lái)要來(lái)談?wù)?@ 這個(gè)符號(hào),你可以把他想成是一種語(yǔ)法的符號(hào)。
def my_logging(func):
def wrapper():
print('logging - {} is running'.format(func.__name__))
func() # run func() Equivalent run f1()
return wrapper
@my_logging
def f1():
print("f1")
f1()
當(dāng)有了 @ 這個(gè)語(yǔ)法的幫忙,就可以將 f1 = my_logging(f1) 省略,直接使用 f1() 即可。
看完上述內(nèi)容,你們對(duì)Python中強(qiáng)大的裝飾器Decorators的工作原理有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。