python裝飾器 python裝飾器完全指南之一

2021-10-11 19:51:10 字數 2065 閱讀 3782

設我們有一組函式,它們有共同的錯誤處理方法,比如列印日誌和記錄審計資訊等。很顯然,在每乙個函式中都重複這些邏輯是不恰當的,它們應該被提煉到乙個函式裡,在這個函式的保護下,再呼叫我們的業務邏輯處理功能。

儘管錯誤處理可能佔據**的主要部分,但業務邏輯才是程式的核心價值。因此,從**結構上看,錯誤處理應該處於可被忽略的非中心地帶。如果我們每次呼叫業務邏輯處理功能前,都要先顯式地從乙個錯誤處理函式開始,這種寫法顯然是頭重腳輕,也會打斷**閱讀者的思緒。基於這些原因,開發語言引入了面向切面的程式設計(aop):把與主業務無關的事情,放到**之外去做。

裝飾器是aop程式設計中不可缺少的語法糖。通過裝飾器語法,可以使得程式更簡潔易讀。本文對裝飾器的基礎原理、一般寫法、corner case和常見場景進行了**。

三個系列共三篇文章,可能是網際網路上最全、最深入的python裝飾器指南之一。

假設我們有乙個功能函式(從現在開始,我們把被裝飾器修飾,完成業務邏輯的那些函式稱作功能函式,以區別於裝飾器函式),出於除錯目的,我們希望列印出它的引數及每次呼叫的返回值。

假設功能函式如下:

# block 1def buggy_incr_by(number):  import random  return random.randint(0,10) + number
我們可以定義這樣乙個函式:

現在,運用裝飾器語法:

# block 3@snoopdef buggy_incr_by(number):  import random  return random.randint(0,10) + number# call and check the resultbuggy_incr_by(3)# --- output --->>> invoke buggy_incr_by with parameter: 3<<< buggy_incr_by returned 13
現在我們來看一看這一切是如何發生的。

這裡最基本的原理有:

1. 在python中,function(函式)也是一種物件(當不帶括號引用時)。你可以任意選擇乙個函式f,通過dir(f)來檢視它有哪些屬性。

2. 在函式內也可以定義函式,並返回這個定義的函式物件。這是因為根據原理1,函式本身也是物件。

3. 模組載入器呼叫exec_module時,會查詢和解析@語句,通過執行 func = decorator(func),重新定義功能函式。

在上面的例子中,我們定義了裝飾器函式snoop,它接受乙個規定好的引數(必須),即功能函式物件本身。decorator的主要功能是定義並返回乙個函式物件(下面稱之為替換函式)。這個函式物件中,完成我們需要的面向切面的功能,並且呼叫功能函式,返回其返回值。

當上述**所在的模組檔案被importlib載入並執行時,載入器(loader)發現存在'@'語法糖,於是執行:

# block 4buggy_incr_by = snoop(buggy_incr_by)
下面是寫乙個最簡單的裝飾器時的一般要訣:

1. 裝飾器decorator只接受乙個形參(名字可以任意取),這個形參將模組載入器呼叫exec_module時,從@註解的下一行函式的定義中找到被定義的函式物件傳入。見上乙個**塊的說明。

3. 在新增裝飾器註解(即'@'語法)時,不需要顯式地將功能函式引數傳給裝飾器,這將由模組載入器自動完成。因此,如果裝飾器只有這乙個引數,註解中必須是不帶括號引用,見上面第2行。

通過上述分析,我們還有幾個重要的結論:

我們在第11行放置了乙個斷點,執行之後,我們檢視堆疊資訊如下:

函式作為一種物件,它有以下元屬性:

通過使用setattr,我們可以很容易替換掉這些資訊。我們看到buggy_incr_by現在有了新的名字,即'gime new name'

注意第3行的注釋。很顯然functools.wraps需要這個引數,因為它要從func中獲取`__name__`,` __qualname__`, `__doc__`等資訊,以便去更新下面的wraper。實際上,functools.wraps是接收了兩個函式物件作為引數。

python裝飾器 Python 裝飾器

簡言之,python裝飾器就是用於拓展原來函式功能的一種函式,這個函式的特殊之處在於它的返回值也是乙個函式,使用python裝飾器的好處就是在不用更改原函式的 前提下給函式增加新的功能。一般而言,我們要想拓展原來函式 最直接的辦法就是侵入 裡面修改,例如 這是我們最原始的的乙個函式,然後我們試圖記錄...

python裝飾器原理 Python裝飾器原理

裝飾器 decorator 是物件導向設計模式的一種,這種模式的核心思想是在不改變原來核心業務邏輯 的情況下,對函式或類物件進行額外的修飾。python中的裝飾器由python直譯器直接支援,其定義形式如下 decorator def core service 要理解上述 的含義,我們從自定義函式裝...

python裝飾器作用 python裝飾器有什麼用

簡言之,python裝飾器就是用於拓展原來函式功能的一種函式,這個函式的特殊之處在於它的返回值也是乙個函式,使用python裝飾器的好處就是在不用更改原函式的 前提下給函式增加新的功能。一般而言,我們要想拓展原來函式 最直接的辦法就是侵入 裡面修改,例如 import time def func p...