深度解析Python裝飾器常見用法與進階技巧
裝飾器的基本原理
裝飾器本質上是一個高階函數(shù),即:以函數(shù)為參數(shù)并返回新函數(shù)的函數(shù)。它可以在不修改原始函數(shù)代碼的前提下,動態(tài)地為其添加功能。
def my_decorator(func):
def wrapper(*args, **kwargs):
print('Before function call')
result = func(*args, **kwargs)
print('After function call')
return result
return wrapper
@my_decorator
def say_hello():
print('Hello, world!')
say_hello()
輸出:
Before function call
Hello, world!
After function call
函數(shù)裝飾器的常見用法
1.日志記錄
import logging
def log_decorator(func):
def wrapper(*args, **kwargs):
logging.info(f'Calling {func.__name__}')
return func(*args, **kwargs)
return wrapper
2.權限校驗
def require_admin(func):
def wrapper(user, *args, **kwargs):
if not user.is_admin:
raise PermissionError('Admin required')
return func(user, *args, **kwargs)
return wrapper
3.性能分析
import time
def timeit(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f'{func.__name__} took {end - start:.4f}s')
return result
return wrapper
4.緩存機制
from functools import lru_cache
@lru_cache(maxsize=128)
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)
帶參數(shù)的裝飾器
帶參數(shù)的裝飾器需要再包一層函數(shù):
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet():
print('Hello!')
類裝飾器與方法裝飾器
類裝飾器
可以用于增強類的功能:
def singleton(cls):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class Database:
pass
方法裝飾器
與函數(shù)裝飾器類似,但要注意 self 的傳遞:
def method_logger(func):
def wrapper(self, *args, **kwargs):
print(f'Calling {func.__name__} of {self}')
return func(self, *args, **kwargs)
return wrapper
class MyClass:
@method_logger
def foo(self):
print('foo called')
裝飾器的嵌套與組合
多個裝飾器可以疊加使用,執(zhí)行順序為自下而上:
@decorator_a
@decorator_b
def func():
pass
# 等價于 func = decorator_a(decorator_b(func))
進階技巧:保留元信息與類型提示
裝飾器會改變被裝飾函數(shù)的元信息(如__name__, __doc__),推薦用 functools.wraps 保留原信息:
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
對于類型提示,可以直接在裝飾器和被裝飾函數(shù)中添加 type hints。
裝飾器最佳實踐
- 始終使用 functools.wraps 保留函數(shù)元信息
- 為裝飾器編寫單元測試,確保功能可復用且無副作用
- 合理使用裝飾器,避免過度嵌套導致調試困難
- 利用標準庫裝飾器(如 @staticmethod, @classmethod, @property, @lru_cache)提升開發(fā)效率
- 為裝飾器添加類型提示和文檔字符串
總結
Python 裝飾器讓我們以聲明式、可復用的方式增強函數(shù)和類的行為。掌握裝飾器的原理與用法,不僅能提升代碼的可讀性和復用性,更能讓你的 Python 項目更具專業(yè)水準。建議在實際開發(fā)中多加練習,靈活運用裝飾器解決實際問題。
到此這篇關于深度解析Python裝飾器常見用法與進階技巧的文章就介紹到這了,更多相關Python裝飾器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
python內置函數(shù)breakpoint()與bytearray()示例詳解
本文給大家分享的是python內置函數(shù)breakpoint()與bytearray()的相關資料,并給大家附上了詳細代碼,有需要的小伙伴可以參考下2017-04-04
Python實現(xiàn)TXT數(shù)據(jù)轉三維矩陣
在數(shù)據(jù)處理和分析中,將文本文件中的數(shù)據(jù)轉換為三維矩陣是一個常見的任務,本文將詳細介紹如何使用Python實現(xiàn)這一任務,感興趣的小伙伴可以了解下2024-01-01
Python用matplotlib庫畫圖中文和負號顯示為方框的問題解決
matplotlib中畫圖的時候會遇到負號顯示為方框的問題,下面這篇文章主要給大家介紹了關于Python用matplotlib庫畫圖中文和負號顯示為方框的問題解決,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-07-07
Python實現(xiàn)棧的方法詳解【基于數(shù)組和單鏈表兩種方法】
這篇文章主要介紹了Python實現(xiàn)棧的方法,結合實例形式詳細分析了Python基于數(shù)組和單鏈表兩種方法定義棧的相關操作技巧,需要的朋友可以參考下2020-02-02
基于SQLAlchemy實現(xiàn)操作MySQL并執(zhí)行原生sql語句
這篇文章主要介紹了基于SQLAlchemy實現(xiàn)操作MySQL并執(zhí)行原生sql語句,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06
Python使用gluon/mxnet模塊實現(xiàn)的mnist手寫數(shù)字識別功能完整示例
這篇文章主要介紹了Python使用gluon/mxnet模塊實現(xiàn)的mnist手寫數(shù)字識別功能,結合完整實例形式分析了Python調用gluon/mxnet模塊識別手寫字的具體實現(xiàn)技巧,需要的朋友可以參考下2019-12-12
python sys.stdin和sys.stdout的用法說明
這篇文章主要介紹了python sys.stdin和sys.stdout的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03
pandas實現(xiàn)excel中的數(shù)據(jù)透視表和Vlookup函數(shù)功能代碼
今天小編就為大家分享一篇pandas實現(xiàn)excel中的數(shù)據(jù)透視表和Vlookup函數(shù)功能代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02

