Python裝飾器的前世今生!

來源:互聯網
上載者:User

標籤:好的   沒有   活性   代碼   method   世界   Oday   cto   SM   

這樣做邏輯上是沒問題的,功能是實現了,但是我們調用的時候不再是調用真正的商務邏輯today函數,而是換成了logging_tool函數,這就破壞了原有的代碼結構,為了支援日誌功能,原有代碼需要大幅修改,那麼有沒有更好的方式的呢?當然有,答案就是裝飾器。

二、開天闢地

一個簡單的裝飾器

以上也是裝飾器的原理!!!

三、Pythonic世界的初探

@文法糖 接觸 Python 有一段時間的話,對 @ 符號一定不陌生了,沒錯 @ 符號就是裝飾器的文法糖,它放在函數開始定義的地方,這樣就可以省略最後一步再次賦值的操作

有了 @ ,我們就可以省去today = logging_tool(today)這一句了,直接調用 today() 即可得到想要的結果。 不需要對today() 函數做任何修改,只需在定義的地方加上裝飾器 ,調用的時候還是和以前一樣。 如果我們有其他的類似函數,可以繼續調用裝飾器來修飾函數 ,而不用重複修改函數或者增加新的封裝。這樣,提高程式可重複利用性,並增加程式的可讀性。

裝飾器在 Python 使用之所以如此方便,歸因於 Python函數能像普通的對象一樣能作為參數傳遞給其他函數,可以被賦值給其他變數,可以作為傳回值,可以被定義在另外一個函數內。

2、讓裝飾器同時支援帶參數或不帶參數

如上所示,參數有兩種類型,一種是字串,另一種是可調用的函數類型。因此,通過對參數類型的判斷即可實現支援帶參數和不帶參數的兩種情況。

3、類裝飾器

裝飾器不僅可以是函數,還可以是類,相比函數裝飾器,類裝飾器具有靈活度大、高內聚、封裝性等優點。使用類裝飾器主要依靠類的__call__方法,當使用 @ 形式將裝飾器附加到函數上時,就會調用此方法。

(1)樣本一、被裝飾函數不帶參數

(3)樣本三、不依賴初始化函數,單獨使用__call__函數實現(體現類裝飾器靈活性大、高內聚、封裝性高的特點) 實現當一些重要函數執行時,列印日誌到一個檔案中,同時發送一個通知給使用者

進一步擴充,給LogTool建立子類,來添加email的功能:

4、裝飾函數 -> 裝飾類

(1)函數層面的裝飾器很常見,以一個函數作為輸入,返回一個新的函數; (2)類層面的裝飾其實也類似,已一個類作為輸入,返回一個新的類;

例如:給一個已有的類添加長度屬性和getter、setter方法

五、上古神器

1、@property -> getter/setter方法

樣本:給一個Student添加score屬性的getter、setter方法

2、@classmethod、@staticmethod

(1)@classmethod 類方法:定義備選構造器,第一個參數是類本身(參數名不限制,一般用cls) (2)@staticmethod 靜態方法:跟類別關係緊密的函數

簡單原理樣本:

3、@functools.wraps

裝飾器極大地複用了代碼,但它有一個缺點:因為返回的是嵌套的函數對象wrapper,不是原函數,導致原函數的元資訊丟失,比如函數的docstring、 name 、參數列表等資訊。不過呢,辦法總比困難多,我們可以通過@functools.wraps將原函數的元資訊拷貝到裝飾器裡面的func函數中,使得裝飾器裡面的func和原函數有一樣的元資訊。

@functools.wraps讓我們可以通過屬性__wrapped__直接存取被裝飾的函數,同時讓被裝飾函數正確暴露底層的參數簽名資訊

countdown.__wrapped__(1000) # 訪問被裝飾的函數print(inspect.signature(countdown)) # 輸出被裝飾函數的簽名資訊

4、Easter egg

(1) 定義一個接受參數的封裝器

@decorator(x, y, z)def func(a, b):pass

等價於

func = decorator(x, y, z)(func)

即:decorator(x, y, z)的返回結果必須是一個可調用的對象,它接受一個函數作為參數並封裝它。

(2)一個函數可以同時定義多個裝飾器,比如:

歡迎關注我的部落格或者公眾號:https://home.cnblogs.com/u/Python1234/ Python學習交流

Python裝飾器的前世今生!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.