圖片來源:(https://forum.gamer.com.tw/Co.php?bsn=43473&sn=47504)
一種特殊的函式,允許在不修改原函數定義的情況下,在函數調用前後執行特定的代碼。簡單來說,裝飾器就像是一個函式的「裝飾品」,可以為函式增加額外的功能
增加函式功能
:計算函式執行時間、記錄函數呼叫紀錄、檢查函式輸入參數等簡化重複性程式碼
:將共用的程式碼抽離到裝飾器中,避免重複寫程式碼AOP (Aspect-Oriented Programming)
:將橫切 關注點 (cross-cutting concerns)
模組化,例如:日誌記錄、錯誤處理@decorator_name
def function_to_decorate():
# function body
@decorator_name
:這行語法表示將 decorator_name
裝飾器應用 function_to_decorate
函式
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
定義裝飾器函式
:my_decorator
函式接受一個函式作為參數,並返回一個新的函式 wrapper
創建內部函式
:wrapper
函式包含了額外的功能,例如在原函式執行前後打印一些訊息使用 @ 語法
:@my_decorator
這行代碼表示將 say_hello
函式傳入 my_decorator
函式,並將返回的 wrapper
函式賦給 say_hello
定義裝飾器函式
:這個函式接收一個函式作為參數,並返回一個新的函式裝飾器函式內部定義一個內嵌函式
: 這個內嵌函式會在原函式被調用時執行內嵌函式中,可以加入額外的程式碼
: 例如:在原函式執行前或後打印訊息、檢查參數、計算執行時間內嵌函式中,呼叫原函式
: 將原函式的返回值返回計算函式執行時間
import time
def timer(func):
def wrapper_func(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"函式 {func.__name__} 執行時間: {end_time - start_time:.4f} 秒")
return result
return wrapper_func
@timer
def my_function(x, y):
time.sleep(2) # 模擬耗時操作
return x + y
result = my_function(3, 4)
print(result)
檢查函式輸入參數
def check_input(func):
def wrapper_func(*args, **kwargs):
if args[0] < 0:
raise ValueError("輸入值不能為負數")
return func(*args, **kwargs)
return wrapper_func
@check_input
def calculate_square(x):
return x * x
result = calculate_square(-2) # 會拋出 ValueError
帶參數的裝飾器
def repeat(num):
def decorator(func):
def wrapper():
for _ in range(num):
func()
return wrapper
return decorator
@repeat(3)
def greet():
print("Hello")
帶參數的被裝飾函式
def my_decorator(func):
def wrapper(*args, **kwargs):
print("函式執行前")
result = func(*args, **kwargs)
print("函式執行後")
return result
return wrapper
Python 裝飾器是一個強大工具,可以讓程式碼更加簡潔、可讀和可維護
通過理解裝飾器的原理和應用場景,可以更有效地利用這個特性來提升程式設計水平