Python 裝飾器(Decorators)入門教學 | Python
在 Python 中,裝飾器(Decorators) 是一個非常強大且優雅的語法特性。它能讓你在不修改原始函式程式碼的情況下,為函式添加額外的功能。本篇將帶你從基礎概念開始,逐步掌握裝飾器的使用方法。
什麼是裝飾器?
裝飾器本質上是一個 函式,它接受另一個函式作為參數,並回傳一個新的函式。這個概念建立在 Python 中「函式是一等公民(First-Class Object)」的基礎上,也就是函式可以被當作變數傳遞、作為參數傳入其他函式。
# 裝飾器的基本結構
def my_decorator(func):
def wrapper():
print("函式執行前")
func()
print("函式執行後")
return wrapper
使用 @ 語法
Python 提供了 @ 語法糖來簡化裝飾器的使用。以下兩種寫法是等價的:
# 方法一:手動套用
def say_hello():
print("Hello!")
say_hello = my_decorator(say_hello)
# 方法二:使用 @ 語法糖(推薦)
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# 輸出:
# 函式執行前
# Hello!
# 函式執行後
處理函式參數
實際開發中,被裝飾的函式通常會有參數。我們可以使用 *args 和 **kwargs 來處理任意數量的參數:
from functools import wraps
def my_decorator(func):
@wraps(func) # 保留原函式的名稱與文件字串
def wrapper(*args, **kwargs):
print(f"呼叫函式:{func.__name__}")
result = func(*args, **kwargs)
print("函式執行完畢")
return result
return wrapper
@my_decorator
def greet(name, greeting="你好"):
print(f"{greeting}, {name}!")
greet("Alice")
# 輸出:
# 呼叫函式:greet
# 你好, Alice!
# 函式執行完畢
這裡使用了 functools.wraps,它能保留被裝飾函式的原始資訊(如 __name__、__doc__),這是撰寫裝飾器時的最佳實踐。
實用範例:計時裝飾器
裝飾器最常見的應用之一是測量函式的執行時間:
import time
from functools import wraps
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 執行時間:{end - start:.4f} 秒")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
print("完成!")
slow_function()
# 輸出:
# 完成!
# slow_function 執行時間:1.0012 秒
帶參數的裝飾器
有時候我們希望裝飾器本身也能接受參數,這需要再多包一層函式:
from functools import wraps
def repeat(n):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def say(message):
print(message)
say("Hello!")
# 輸出:
# Hello!
# Hello!
# Hello!
@repeat(3) 會先呼叫 repeat(3) 取得真正的裝飾器,再將 say 函式傳入該裝飾器。
內建裝飾器
Python 本身也提供了幾個常用的內建裝飾器,在物件導向程式設計中經常使用:
class MyClass:
@staticmethod # 靜態方法,不需要 self 或 cls 參數
def static_method():
print("這是靜態方法")
@classmethod # 類別方法,第一個參數為 cls
def class_method(cls):
print(f"這是 {cls.__name__} 的類別方法")
@property # 將方法變為屬性存取
def name(self):
return self._name
總結
裝飾器是 Python 中非常實用的功能,它讓你能以簡潔的方式為函式添加額外行為。核心概念是:裝飾器接收一個函式、回傳一個增強後的函式。記得使用 @wraps 保留原函式資訊,並善用 *args 和 **kwargs 處理任意參數。常見應用包括日誌記錄、效能計時、權限驗證等。希望這篇文章能幫助你掌握這個強大的 Python 語法特性。
裝飾器的基礎是函式,建議先閱讀 Python 函數(Functions)入門指南。想進一步了解內建裝飾器在類別中的應用,可以參考 Python 的物件導向程式設計。