想像你是個繁忙廚房裡的廚師。如果你願意的話,你有一個食譜——一個函數。隨著時間的推移,您會發現大多數菜餚在上桌前都需要淋上一點橄欖油、少許鹽或撒上香草。與其手動為每道菜添加這些最後的修飾,有一個自動應用它們的助手不是很方便嗎?這正是 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> Hello, Alice! </__main__.greeter>
將裝飾器與上下文管理器結合
有時,您需要將裝飾器與資源管理整合。例如,讓我們建立一個裝飾器來對函數的執行進行計時。
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中文網其他相關文章!

在Python中實現工廠模式可以通過創建一個統一的接口來創建不同類型的對象。具體步驟如下:1.定義一個基礎類和多個繼承類,如Vehicle、Car、Plane和Train。 2.創建一個工廠類VehicleFactory,使用create_vehicle方法根據類型參數返回相應的對象實例。 3.通過工廠類實例化對象,如my_car=factory.create_vehicle("car","Tesla")。這種模式提高了代碼的可擴展性和可維護性,但需注意其複雜

在Python中,r或R前綴用於定義原始字符串,忽略所有轉義字符,讓字符串按字面意思解釋。 1)適用於處理正則表達式和文件路徑,避免轉義字符誤解。 2)不適用於需要保留轉義字符的情況,如換行符。使用時需謹慎檢查,以防意外的輸出。

在Python中,__del__方法是對象的析構函數,用於清理資源。 1)不確定的執行時間:依賴垃圾回收機制。 2)循環引用:可能導致無法及時調用,使用weakref模塊處理。 3)異常處理:在__del__中拋出的異常可能被忽略,使用try-except塊捕獲。 4)資源管理的最佳實踐:推薦使用with語句和上下文管理器管理資源。

pop()函數在Python中用於從列表中移除並返回指定位置的元素。 1)不指定索引時,pop()默認移除並返回列表的最後一個元素。 2)指定索引時,pop()移除並返回該索引位置的元素。 3)使用時需注意索引錯誤、性能問題、替代方法和列表的可變性。

Python進行圖像處理主要使用Pillow和OpenCV兩大庫。 Pillow適合簡單圖像處理,如加水印,代碼簡潔易用;OpenCV適用於復雜圖像處理和計算機視覺,如邊緣檢測,性能優越但需注意內存管理。

在Python中實現PCA可以通過手動編寫代碼或使用scikit-learn庫。手動實現PCA包括以下步驟:1)中心化數據,2)計算協方差矩陣,3)計算特徵值和特徵向量,4)排序並選擇主成分,5)投影數據到新空間。手動實現有助於深入理解算法,但scikit-learn提供更便捷的功能。

在Python中計算對數是一件非常簡單卻又充滿趣味的事情。讓我們從最基本的問題開始:怎樣用Python計算對數?用Python計算對數的基本方法Python的math模塊提供了計算對數的函數。讓我們來看一個簡單的例子:importmath#計算自然對數(底數為e)x=10natural_log=math.log(x)print(f"自然對數log({x})={natural_log}")#計算以10為底的對數log_base_10=math.log10(x)pri

要在Python中實現線性回歸,我們可以從多個角度出發。這不僅僅是一個簡單的函數調用,而是涉及到統計學、數學優化和機器學習的綜合應用。讓我們深入探討一下這個過程。在Python中實現線性回歸最常見的方法是使用scikit-learn庫,它提供了簡便且高效的工具。然而,如果我們想要更深入地理解線性回歸的原理和實現細節,我們也可以從頭開始編寫自己的線性回歸算法。使用scikit-learn實現線性回歸scikit-learn庫封裝了線性回歸的實現,使得我們可以輕鬆地進行建模和預測。下面是一個使用sc


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

記事本++7.3.1
好用且免費的程式碼編輯器

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。