Python 裝飾器是一種高級功能,允許你在不修改原始函數代碼的情況下,動態地修改或擴展函數的行為。
基本語法
裝飾器是一種特殊的函數,其基本語法如下:
def decorator_function(func):def wrapper(*args, **kwargs):# 在調用原始函數之前的操作result = func(*args, **kwargs)# 在調用原始函數之后的操作return resultreturn wrapper
常用命令
@decorator_function
:將裝飾器應用到函數上的語法糖。decorator_function
:裝飾器函數本身。
示例
示例 1:簡單裝飾器
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()
示例 2:帶參數的裝飾器
def repeat(num_times):def decorator_repeat(func):def wrapper(*args, **kwargs):for _ in range(num_times):result = func(*args, **kwargs)return resultreturn wrapperreturn decorator_repeat@repeat(num_times=3)
def greet(name):print(f"Hello {name}")greet("Alice")
應用場景
1. 日志記錄
裝飾器在日志記錄中發揮著重要作用,它可以捕獲函數的輸入參數、執行時間以及輸出結果,從而方便開發人員跟蹤函數的執行過程和調試代碼。通過裝飾器記錄日志,可以提高代碼的可讀性和可維護性。
示例代碼:
import logging
import timedef log_decorator(func):def wrapper(*args, **kwargs):logging.info(f"Calling function {func.__name__} with args: {args}, kwargs: {kwargs}")start_time = time.time()result = func(*args, **kwargs)end_time = time.time()logging.info(f"Function {func.__name__} executed in {end_time - start_time} seconds with result: {result}")return resultreturn wrapper@log_decorator
def add(x, y):return x + yresult = add(3, 5)
print("Result:", result)
2. 性能監控
裝飾器在性能監控方面也具有重要作用,它可以幫助開發人員監控函數的執行時間,發現潛在的性能瓶頸并進行優化。通過裝飾器進行性能監控,可以提高代碼的效率和性能。
示例代碼:
import timedef performance_decorator(func):def wrapper(*args, **kwargs):start_time = time.time()result = func(*args, **kwargs)end_time = time.time()print(f"Function {func.__name__} executed in {end_time - start_time} seconds")return resultreturn wrapper@performance_decorator
def calculate_factorial(n):factorial = 1for i in range(1, n + 1):factorial *= ireturn factorialresult = calculate_factorial(10)
print("Factorial:", result)
3. 權限驗證
裝飾器可以用于權限驗證,例如檢查用戶是否具有執行特定操作的權限。這種方式使得權限驗證邏輯與業務邏輯分離,提高了代碼的模塊化和可維護性。
示例代碼:
def permission_required(permission):def decorator(func):def wrapper(*args, **kwargs):if check_permission(permission):return func(*args, **kwargs)else:raise PermissionError("Permission denied")return wrapperreturn decoratordef check_permission(permission):# 檢查用戶是否具有指定權限的邏輯return True # 此處僅為示例,實際需根據業務邏輯實現@permission_required("admin")
def delete_user(user_id):# 刪除用戶的邏輯print(f"User {user_id} deleted successfully")delete_user(123)
注意事項
1. 裝飾器順序
當多個裝飾器應用于同一個函數時,它們的執行順序與它們在代碼中的順序相反。這意味著最先定義的裝飾器實際上會最后執行,而最后定義的裝飾器會最先執行。
示例代碼:
def decorator1(func):def wrapper():print("Decorator 1 executed")func()return wrapperdef decorator2(func):def wrapper():print("Decorator 2 executed")func()return wrapper@decorator1
@decorator2
def greet():print("Hello!")greet()
輸出結果為:
Decorator 1 executed
Decorator 2 executed
Hello!
2. 裝飾器的參數
如果裝飾器本身需要接受參數,則需要在裝飾器函數外再包裹一層函數。這樣的裝飾器稱為帶參數的裝飾器。在定義帶參數的裝飾器時,外層函數接受裝飾器參數,內層函數接受被裝飾函數。
示例代碼:
def decorator_with_param(param):def decorator(func):def wrapper():print(f"Decorator with parameter {param} executed")func()return wrapperreturn decorator@decorator_with_param("test")
def greet():print("Hello!")greet()
輸出結果為:
Decorator with parameter test executed
Hello!
總結
裝飾器是 Python 中一種強大的工具,可用于動態修改函數的行為,常用于日志記錄、性能監控、權限驗證等場景。通過合理使用裝飾器,可以提高代碼的靈活性、可重用性和可維護性。