深度解析Python裝飾器常見(jiàn)用法與進(jìn)階技巧
裝飾器的基本原理
裝飾器本質(zhì)上是一個(gè)高階函數(shù),即:以函數(shù)為參數(shù)并返回新函數(shù)的函數(shù)。它可以在不修改原始函數(shù)代碼的前提下,動(dòng)態(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ù)裝飾器的常見(jiàn)用法
1.日志記錄
import logging
def log_decorator(func):
def wrapper(*args, **kwargs):
logging.info(f'Calling {func.__name__}')
return func(*args, **kwargs)
return wrapper
2.權(quán)限校驗(yàn)
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.緩存機(jī)制
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!')
類(lèi)裝飾器與方法裝飾器
類(lèi)裝飾器
可以用于增強(qiáng)類(lèi)的功能:
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ù)裝飾器類(lèi)似,但要注意 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')
裝飾器的嵌套與組合
多個(gè)裝飾器可以疊加使用,執(zhí)行順序?yàn)樽韵露希?/p>
@decorator_a
@decorator_b
def func():
pass
# 等價(jià)于 func = decorator_a(decorator_b(func))
進(jìn)階技巧:保留元信息與類(lèi)型提示
裝飾器會(huì)改變被裝飾函數(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
對(duì)于類(lèi)型提示,可以直接在裝飾器和被裝飾函數(shù)中添加 type hints。
裝飾器最佳實(shí)踐
- 始終使用 functools.wraps 保留函數(shù)元信息
- 為裝飾器編寫(xiě)單元測(cè)試,確保功能可復(fù)用且無(wú)副作用
- 合理使用裝飾器,避免過(guò)度嵌套導(dǎo)致調(diào)試?yán)щy
- 利用標(biāo)準(zhǔn)庫(kù)裝飾器(如 @staticmethod, @classmethod, @property, @lru_cache)提升開(kāi)發(fā)效率
- 為裝飾器添加類(lèi)型提示和文檔字符串
總結(jié)
Python 裝飾器讓我們以聲明式、可復(fù)用的方式增強(qiáng)函數(shù)和類(lèi)的行為。掌握裝飾器的原理與用法,不僅能提升代碼的可讀性和復(fù)用性,更能讓你的 Python 項(xiàng)目更具專(zhuān)業(yè)水準(zhǔn)。建議在實(shí)際開(kāi)發(fā)中多加練習(xí),靈活運(yùn)用裝飾器解決實(shí)際問(wèn)題。
到此這篇關(guān)于深度解析Python裝飾器常見(jiàn)用法與進(jìn)階技巧的文章就介紹到這了,更多相關(guān)Python裝飾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python內(nèi)置函數(shù)breakpoint()與bytearray()示例詳解
本文給大家分享的是python內(nèi)置函數(shù)breakpoint()與bytearray()的相關(guān)資料,并給大家附上了詳細(xì)代碼,有需要的小伙伴可以參考下2017-04-04
Python實(shí)現(xiàn)TXT數(shù)據(jù)轉(zhuǎn)三維矩陣
在數(shù)據(jù)處理和分析中,將文本文件中的數(shù)據(jù)轉(zhuǎn)換為三維矩陣是一個(gè)常見(jiàn)的任務(wù),本文將詳細(xì)介紹如何使用Python實(shí)現(xiàn)這一任務(wù),感興趣的小伙伴可以了解下2024-01-01
Python用matplotlib庫(kù)畫(huà)圖中文和負(fù)號(hào)顯示為方框的問(wèn)題解決
matplotlib中畫(huà)圖的時(shí)候會(huì)遇到負(fù)號(hào)顯示為方框的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于Python用matplotlib庫(kù)畫(huà)圖中文和負(fù)號(hào)顯示為方框的問(wèn)題解決,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
Python實(shí)現(xiàn)棧的方法詳解【基于數(shù)組和單鏈表兩種方法】
這篇文章主要介紹了Python實(shí)現(xiàn)棧的方法,結(jié)合實(shí)例形式詳細(xì)分析了Python基于數(shù)組和單鏈表兩種方法定義棧的相關(guān)操作技巧,需要的朋友可以參考下2020-02-02
基于SQLAlchemy實(shí)現(xiàn)操作MySQL并執(zhí)行原生sql語(yǔ)句
這篇文章主要介紹了基于SQLAlchemy實(shí)現(xiàn)操作MySQL并執(zhí)行原生sql語(yǔ)句,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
Python使用gluon/mxnet模塊實(shí)現(xiàn)的mnist手寫(xiě)數(shù)字識(shí)別功能完整示例
這篇文章主要介紹了Python使用gluon/mxnet模塊實(shí)現(xiàn)的mnist手寫(xiě)數(shù)字識(shí)別功能,結(jié)合完整實(shí)例形式分析了Python調(diào)用gluon/mxnet模塊識(shí)別手寫(xiě)字的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-12-12
python sys.stdin和sys.stdout的用法說(shuō)明
這篇文章主要介紹了python sys.stdin和sys.stdout的用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03
pandas實(shí)現(xiàn)excel中的數(shù)據(jù)透視表和Vlookup函數(shù)功能代碼
今天小編就為大家分享一篇pandas實(shí)現(xiàn)excel中的數(shù)據(jù)透視表和Vlookup函數(shù)功能代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02

