Python 函數裝飾器 (Function Decorator) 筆記
✅ 什麼是函數裝飾器?
-
函數裝飾器(
Function Decorator
)是一種用來修改或擴展函數功能的設計模式。它允許在不改變函數本身的情況下,將額外的邏輯附加到函數上。 -
函數裝飾器是高階函數
Higher-order Function
:接收一個函數作為參數,並返回一個包裹在該函數的新函數 (Wrapper
)。
函數裝飾器是 Python 中一種強大的功能,允許我們修改或擴展現有函數的行為,而無需改變函數的代碼。它是一種語法糖,基於高階函數的概念,使得函數變得更加靈活和可重複使用。
函數裝飾器的結構
def decorator(func):
def wrapper(*args, **kwargs):
# 在此處進行一些處理或擴展功能
return func(*args, **kwargs)
return wrapper
decorator(func)
:裝飾器函數,接收被裝飾的函數func
。wrapper(*args, **kwargs)
:內部包裝函數,可以修改或擴展func
的行為。return wrapper
:返回包裝函數wrapper
,這樣我們就能在裝飾器中處理邏輯。
💡 為何要使用裝飾器?
- 功能擴展:可以在不修改函數內容的情況下,擴展或修改其行為。
- 程式碼重用:可以將重複的邏輯提取出來,放在裝飾器中,減少重複代碼。
- 增強函數功能:通過裝飾器可以給函數增加額外的功能,像是日誌、權限檢查、緩存等。
📝 基本範例
def simple_decorator(func):
def wrapper():
print("Before function call.")
func()
print("After function call.")
return wrapper
@simple_decorator
def say_hello():
print("Hello!")
say_hello()
輸出:
Before function call.
Hello!
After function call.
如何運作:
@simple_decorator
是裝飾器的語法糖,等同於say_hello = simple_decorator(say_hello)
。- 裝飾器會包裝
say_hello
函數,使它在被調用時執行額外的邏輯。
🔄 帶參數的裝飾器
如果需要裝飾器接受參數,可以再定義一層函數。這樣可以讓裝飾器變得更加通用。
帶參數範例
def calculator(func):
def calculate_height(weight, height):
def square_height(height):
height_in_meters = height / 100
return height_in_meters
return func(weight, square_height(height))
return calculate_height
@calculator
def bmi_calculator(weight, height):
return weight / (height * height)
result = bmi_calculator(50, 160)
print(result) # 19.531249999999996
解釋:
calculator
是裝飾器,接受bmi_calculator
作為參數。- 在
calculate_height
函數內部,我們調用square_height
函數來將身高轉換為米,然後再計算 BMI。
帶參數裝飾器的工作原理:
@calculator
會讓bmi_calculator
被calculator
包裝。- 裝飾器內的
calculate_height
會在bmi_calculator
函數之前執行,進行額外處理。
🔑 函數裝飾器的好處:
- 可以動態地修改函數的行為。
- 使得原始函數更簡潔,擴展的邏輯集中於裝飾器內部,提升代碼可維護性。
- 允許代碼更加模組化和解耦。
📚 常見應用場景:
-
日誌記錄:記錄函數的調用及參數。
範例:
def log_decorator(func): def wrapper(*args, **kwargs): print(f"Calling {func.__name__} with arguments: {args}, {kwargs}") return func(*args, **kwargs) return wrapper @log_decorator def add(a, b): return a + b add(3, 4) # 輸出: Calling add with arguments: (3, 4), {}
-
計時器:計算函數執行所花的時間。
範例:
import time def timer_decorator(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"Execution time: {end_time - start_time} seconds") return result return wrapper @timer_decorator def slow_function(): time.sleep(2) slow_function() # 輸出: Execution time: 2.0xxxxxx seconds
-
權限檢查:在函數執行之前檢查用戶權限。
範例:
def permission_check(func): def wrapper(user_role, *args, **kwargs): if user_role != "admin": raise PermissionError("You do not have permission to access this function.") return func(user_role, *args, **kwargs) return wrapper @permission_check def delete_user(user_role, user_id): print(f"User {user_id} deleted.") delete_user("admin", 123) # 正常執行 delete_user("guest", 123) # 會拋出 PermissionError
-
緩存:為函數結果加上緩存,避免重複計算。
範例:
def cache_decorator(func): cache = {} def wrapper(*args, **kwargs): if args in cache: print("Returning cached result") return cache[args] result = func(*args, **kwargs) cache[args] = result return result return wrapper @cache_decorator def expensive_computation(x): print("Performing expensive computation...") return x * x expensive_computation(10) # 輸出: Performing expensive computation... expensive_computation(10) # 輸出: Returning cached result
這樣的範例可以幫助更好地理解每個應用場景,並將裝飾器的應用擴展到真實開發中。
對於新手來說,理解
function decorator
可以從以下幾個步驟入手:
-
理解函數是物件:首先,理解 Python 函數是物件,可以作為參數傳遞給其他函數。
-
學會基本裝飾器範例:如日誌記錄、計時等。先從簡單的範例開始,逐步理解其運作。
-
從簡單的實例開始:不要一開始就嘗試複雜的場景。實踐簡單的範例來熟悉裝飾器的結構。
-
了解如何使用
@
語法:@decorator
是 Python 中簡化使用裝飾器的語法,它背後實際上是將函數傳遞給裝飾器。
學會裝飾器後,可以根據需求進行進一步的學習和應用。
面試時如何回答 function decorator
1. 簡單解釋:
裝飾器是一種用來修改或擴展函數功能的設計模式。它允許在不改變函數本身的情況下,將額外的邏輯附加到函數上。
2. 常見應用場景:
- 日誌記錄
- 計時
- 權限檢查
- 緩存
3. 基本結構:
- 裝飾器是高階函數:接收一個函數作為參數,並返回一個包裹該函數的新函數。
4. 示範範例:
def decorator(func):
def wrapper():
print("Before function execution")
func()
print("After function execution")
return wrapper
@decorator
def greet():
print("Hello!")
5. 考試重點:
- 知道裝飾器的語法
@decorator
- 解釋如何將邏輯封裝到函數外部
- 理解裝飾器的用途與運作原理