Python,十個高效有用的裝飾器
在 Python 編程領域,裝飾器是一種極具威力的工具,它如同為函數或類披上了一層神奇的 外衣,能夠在不修改原始代碼的前提下,巧妙地更改或強化其行為表現。
本質上,裝飾器是一個函數,它以其他函數或類作為輸入參數,經處理后返回一個新的函數或類。
在實際應用中,我們只需在目標函數或類之前添加 @ 符號,即可快速便捷地應用裝飾器。
接下來,開發(fā)常用的10種裝飾器示例代碼:
1. @timer
用于統(tǒng)計函數執(zhí)行時間,對性能分析極為有利,可迅速定位代碼中的性能瓶頸。
import time
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}s")
return result
return wrapper
2. @debug
在調試過程中,該裝飾器可打印函數的參數及返回值,便于我們迅速找到問題根源。
def debug(func):
def wrapper(*args, **kwargs):
print(f"[DEBUG] {func.__name__} args: {args}, kwargs: {kwargs}")
result = func(*args, **kwargs)
print(f"[DEBUG] {func.__name__} returned: {result}")
return result
return wrapper
3. @retry
當網絡請求等操作失敗時,此裝飾器能自動進行重試,有效增強程序的魯棒性。
def retry(max_attempts=3, delay=1):
def decorator(func):
def wrapper(*args, **kwargs):
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"Attempt {attempt + 1} failed: {e}")
time.sleep(delay)
raise Exception("Max retries exceeded")
return wrapper
return decorator
4. @deprecated
用于標記已過時的函數,提醒用戶及時替換為新函數。
import warnings
def deprecated(func):
def wrapper(*args, **kwargs):
warnings.warn(f"{func.__name__} is deprecated", DeprecationWarning)
return func(*args, **kwargs)
return wrapper
return wrapper
5. @permission
Web API 中,用于檢查用戶是否具備相應的權限,如是否為 admin 角色。
def permission(perm):
def decorator(func):
def wrapper(user, *args, **kwargs):
if user.permission != perm:
raise PermissionError("Access denied")
return func(user, *args, **kwargs)
return wrapper
return decorator
6. @validate
確保輸入數據符合預期的格式,如數據類型、范圍等,若不符合則拋出異常。
def validate(*validators):
def decorator(func):
def wrapper(*args, **kwargs):
for i, val in enumerate(args):
if not validators[i](val):
raise ValueError(f"Invalid argument: {val}")
return func(*args, **kwargs)
return wrapper
return decorator
return decorator
7. @login
確保用戶已認證登錄,防止未經授權的操作。
def login(func):
def wrapper(user, *args, **kwargs):
if not user.is_authenticated:
raise Exception("User not logged in")
return func(user, *args, **kwargs)
return wrapper
8. @log_results
將函數輸出持久化保存,方便后續(xù)查看函數運行結果。
def log_results(filename):
def decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
with open(filename, "a") as f:
f.write(f"{func.__name__}: {result}\n")
return result
return wrapper
return decorator
9. @rate_limit
限制 API 調用頻率,防范 DDoS 攻擊或 API 被濫用。
from redis import Redis
redis = Redis()
def rate_limit(key, limit=100, period=3600):
def decorator(func):
def wrapper(*args, **kwargs):
count = redis.get(key) or0
if int(count) >= limit:
raise Exception("API rate limit exceeded")
redis.incr(key, 1)
redis.expire(key, period)
return func(*args, **kwargs)
return wrapper
return decorator
10. @singleton
確保一個類只有一個實例,在特定場景下非常有用。
def singleton(cls):
instances = {}
def wrapper(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
熟練掌握裝飾器的運用,能夠極大簡化開發(fā)流程,使代碼更加健壯可靠。在大型項目開發(fā)中,借助裝飾器實現關注點分離,如將日志記錄、權限管理等功能與核心業(yè)務邏輯分開處理,可顯著提升開發(fā)效率。