首頁 > 後端開發 > Python教學 > 進階 Python 裝飾器:提升您的程式碼

進階 Python 裝飾器:提升您的程式碼

Patricia Arquette
發布: 2025-01-06 03:42:48
原創
981 人瀏覽過

Advanced Python Decorators: Elevating Your Code

想像你是個繁忙廚房裡的廚師。如果你願意的話,你有一個食譜——一個函數。隨著時間的推移,您會發現大多數菜餚在上桌前都需要淋上一點橄欖油、少許鹽或撒上香草。與其手動為每道菜添加這些最後的修飾,有一個自動應用它們的助手不是很方便嗎?這正是 Python 裝飾器可以為您的程式碼做的事情——以優雅、可重複使用且富有表現力的方式添加功能。

在本文中,我們將探索高階 Python 裝飾器的世界。我們將超越基礎知識,深入研究參數化裝飾器、可堆疊裝飾器,甚至帶有類別的裝飾器。我們還將重點介紹最佳實踐和要避免的陷阱。準備好?開始做飯吧!

重溫基礎知識

在深入探討之前,讓我們先回顧一下基礎知識。 Python 中的裝飾器只是一個函數,它接受另一個函數(或方法)作為參數,對其進行擴充,然後傳回一個新函數。這是一個例子:

# Basic decorator example
def simple_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}...")
        result = func(*args, **kwargs)
        print(f"{func.__name__} finished.")
        return result
    return wrapper

@simple_decorator
def say_hello():
    print("Hello, world!")

say_hello()
登入後複製
登入後複製

輸出:

Calling say_hello...
Hello, world!
say_hello finished.
登入後複製
登入後複製

現在,讓我們進入高階用例。

參數化裝飾器

有時,裝飾器需要接受自己的參數。例如,如果我們想要一個裝飾器來記錄不同程度的訊息(資訊、偵錯、錯誤)怎麼辦?

# Parameterized decorator example
def log(level):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"[{level}] Calling {func.__name__}...")
            result = func(*args, **kwargs)
            print(f"[{level}] {func.__name__} finished.")
            return result
        return wrapper
    return decorator

@log("INFO")
def process_data():
    print("Processing data...")

process_data()
登入後複製

輸出:

[INFO] Calling process_data...
Processing data...
[INFO] process_data finished.
登入後複製

這種分層結構(傳回裝飾器的函數)是創建靈活的參數化裝飾器的關鍵。

可堆疊裝飾器

Python 允許將多個裝飾器應用於單一函數。讓我們建立兩個裝飾器並將它們堆疊起來。

# Stackable decorators

def uppercase(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result.upper()
    return wrapper

def exclaim(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result + "!!!"
    return wrapper

@uppercase
@exclaim
def greet():
    return "hello"

print(greet())
登入後複製

輸出:

HELLO!!!
登入後複製

這裡,裝飾器以自下而上的方式應用:@exclaim 包裝問候,@uppercase 包裝結果。

使用類別作為裝飾器

Python 的一個鮮為人知的功能是類別可以用作裝飾器。當您需要維護狀態時,這特別有用。

# Class-based decorator
class CountCalls:
    def __init__(self, func):
        self.func = func
        self.call_count = 0

    def __call__(self, *args, **kwargs):
        self.call_count += 1
        print(f"Call {self.call_count} to {self.func.__name__}")
        return self.func(*args, **kwargs)

@CountCalls
def say_hello():
    print("Hello!")

say_hello()
say_hello()
登入後複製

輸出:

Call 1 to say_hello
Hello!
Call 2 to say_hello
Hello!
登入後複製

這裡,call 方法使類別能夠像函數一樣運行,從而允許它無縫地包裝目標函數。

方法的裝飾器

裝飾器與類別中的方法一樣有效。然而,正確處理自我是至關重要的。

# Method decorator example
def log_method(func):
    def wrapper(self, *args, **kwargs):
        print(f"Method {func.__name__} called on {self}")
        return func(self, *args, **kwargs)
    return wrapper

class Greeter:
    @log_method
    def greet(self, name):
        print(f"Hello, {name}!")

obj = Greeter()
obj.greet("Alice")
登入後複製

輸出:

Method greet called on <__main__.Greeter object at 0x...>
Hello, Alice!
登入後複製

將裝飾器與上下文管理器結合

有時,您需要將裝飾器與資源管理整合。例如,讓我們建立一個裝飾器來對函數的執行進行計時。

import time

# Timing decorator
def time_it(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end - start:.2f} seconds")
        return result
    return wrapper

@time_it
def slow_function():
    time.sleep(2)
    print("Done sleeping!")

slow_function()
登入後複製

輸出:

# Basic decorator example
def simple_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}...")
        result = func(*args, **kwargs)
        print(f"{func.__name__} finished.")
        return result
    return wrapper

@simple_decorator
def say_hello():
    print("Hello, world!")

say_hello()
登入後複製
登入後複製

最佳實踐

與裝飾器合作時,保持可讀性和可維護性至關重要。這裡有一些提示:

  • 使用 functools.wraps:這會保留原始函數的元資料。
Calling say_hello...
Hello, world!
say_hello finished.
登入後複製
登入後複製
  • 徹底測試:裝飾器可能會引入微妙的錯誤,尤其是在連結多個裝飾器時。

  • 文件裝飾器:清楚記錄每個裝飾器的作用及其預期參數。

  • 避免過度使用:雖然裝飾器很強大,但過度使用它們會使程式碼難以理解。

總結

裝飾器是 Python 最具表現力的功能之一。它們允許您以乾淨、可重複使用的方式擴展和修改行為。從參數化裝飾器到基於類別的實現,可能性是無限的。當你磨練你的技能時,你會發現自己利用裝飾器來編寫更乾淨、更Pythonic的程式碼——也許,就像一位偉大的廚師一樣,在你製作的每一個食譜中創造出你的標誌性風格。

註:AI輔助內容

以上是進階 Python 裝飾器:提升您的程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板