python的裝飾器其實是乙個語法糖,第一行是@跟著乙個表示式;第二行必須以def或者class起始(亦即函式或者class的定義)。
python的裝飾器,必須是可呼叫的物件,而且必須是可以以乙個引數進行呼叫。注意,對返回引數的個數是不做限制的!
那麼,python中有幾種可呼叫物件呢?大致有四種:
1)函式物件,這個不用多說什麼了吧;
2)類物件,我們生成類例項的時候,都是用類物件呼叫生成的;
3)類的三種方法:例項方法、類方法、靜態方法;
4)如果類實現了`__call__`方法,則類的例項物件也是可呼叫的;
裝飾器本質上就是乙個語法糖,它等價於先定義了函式/類之後,將函式物件/類物件作為引數呼叫裝飾器,然後將返回值賦給原本代表函式物件/類物件的變數。
事實上,只要裝飾器能夠成功執行,不管它如何處理的,python都不會報錯。即使返回值不是同類的函式或者類物件,而是其它的什麼東西,比如基本型別,乃至列表/元組都無所謂。
好了,我們現在差不多,就知道裝飾器這玩意是乙個多麼自由的東西了。其實python裡面n多東西都這麼自由。
根據裝飾器的輸入和輸出,我們可以將裝飾器分成如下幾類
1)吃進乙個函式,吐出乙個修飾過的函式。
這是我們自己最常寫的一種裝飾器了,通常我們通過裝飾器,來進行log、快取、型別檢驗、錯誤捕捉等等。
2)吃進乙個函式,返回乙個class物件。
這種情況比較罕見,至少我沒有見過。
3)吃進乙個函式,吐出乙個class的例項。
最典型的,比如property,它可以吃進乙個函式,返回乙個描述器的例項(注意返回的例項的身份肯定是類的屬性)。staticmethod和classmethod也是一樣的道理。
還有一種情況,也就是返回乙個實現了`__call__`方法的class物件的例項。這種相當於乙個可更新環境的閉包,有時候挺有用。
4)吃進乙個函式,吐出乙個不可呼叫物件。
基本上,這是起到乙個提前計算的作用。比如說乙個裝飾器可以接受乙個函式,然後預先計算出函式的返回值,然後直接將返回值賦給原本代表函式物件/類物件的變數。
5)吃進乙個class物件,吐出乙個函式。
比如返回乙個可以使用引數來返回該class物件的例項的函式,但同時也進行log、快取、型別檢驗、錯誤捕捉等等。
6)吃進乙個class物件,吐出乙個class物件。
和第一種類似,只不過是對class物件進行完善,比如functools.total_ordering,它就是可以完善class物件的比較運算的魔術方法。
python裝飾器 python 裝飾器詳解
def outer x def inner y return x y return inner print outer 6 5 11 如 所示,在outer函式內,又定義了乙個inner函式,並且inner函式又引用了外部函式outer的變數x,這就是乙個閉包了。在輸出時,outer 6 5 第乙個...
python裝飾器詳解 python裝飾器詳解
按照 python 的程式設計原則,當乙個函式被定義後,如要修改或擴充套件其功能應盡量避免直接修改函式定義的 段,否則該函式在其他地方被呼叫時將無法正常執行。因此,當需要修改或擴充套件已被定義的函式的功能而不希望直接修改其 時,可以使用裝飾器。先來看乙個簡單的例子 def func1 functio...
詳解Python閉包,裝飾器及類裝飾器
在專案開發中,總會遇到在原 的基礎上新增額外的功能模組,原有的 也許是很久以前所寫,為了新增新功能的 塊,您一般還得重新熟悉源 稍微搞清楚一點它的邏輯,這無疑是一件特別頭疼的事情 今天我們介紹的python裝飾器就能夠很好的解決這類問題 閉包函式 閉包比較簡單,直接上 def sum num1 1 ...