首頁  >  文章  >  後端開發  >  了解 Python 裝飾器:深入探討

了解 Python 裝飾器:深入探討

Barbara Streisand
Barbara Streisand原創
2024-10-30 08:22:28343瀏覽

Python 裝飾器是強大的工具,允許我們修改或增強函數或方法的行為。常見用例包括日誌記錄、授權等。
然而,當被要求定義裝飾器時,很多人可能會說,

它是函數的包裝器。

雖然這在技術上是正確的,但幕後還發生了更多事情。

剖析一個簡單的裝飾器
讓我們探討一個簡單的例子:

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Before calling the function")
        result = func(*args, **kwargs)
        print("After calling the function")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    print(f"Hello, {name}!")

這裡,my_decorator是函數say_hello的裝飾器。當 say_hello 定義後,它會自動傳遞給 my_decorator,將函數呼叫轉換為:
say_hello = my_decorator(say_hello)

這種轉變是什麼時候發生?
這種轉換發生在程式碼編譯期間,特別是當函數定義時,而不是在執行時。

反組譯碼
要了解裝飾器如何在較低層級運作,我們可以使用 dis 模組來檢查裝飾函數的字節碼:

import dis

@my_decorator
def say_hello(name):
    print(f"Hello, {name}!")

dis.dis(say_hello)

字節碼分解

dis.dis(say_hello) 的輸出可能如下圖所示:

Understanding Python Decorators: A Deep Dive
字節碼解釋

  1. 呼叫函數之前

    • LOAD_GLOBAL:載入列印功能。
    • LOAD_CONST:載入訊息「在呼叫函數之前」。
    • CALL_FUNCTION:呼叫列印。
    • POP_TOP:丟棄回傳值。
  2. 呼叫原函數

    • LOAD_DEREF:載入閉包捕獲的原始函數(func)。
    • LOAD_FAST:載入位置和關鍵字參數。
    • BUILD_MAP:為關鍵字參數建立一個新字典。
    • CALL_FUNCTION_EX:使用參數呼叫原始函數。
    • STORE_FAST:將結果儲存在局部變數中。
  3. 呼叫函數後

    • 與第一部分類似,它呼叫 print 輸出「呼叫函數之後」。
    • 回傳結果
    • 載入結果變數並傳回它。

結論
Python 裝飾器不僅僅是函數包裝器;它們使我們能夠在定義時修改函數行為。透過了解它們的工作原理並檢查字節碼,我們可以在專案中更有效地使用裝飾器。

現在就是這樣!如果您還有什麼需要我深入研究的內容,請告訴我!

以上是了解 Python 裝飾器:深入探討的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn