Pylance與python自定義裝飾器類型提示的沖突及解決方案
Python裝飾器是強大的代碼復用工具,但使用自定義裝飾器時,靜態類型檢查器(如Pylance)可能會出現類型提示錯誤,尤其當裝飾器修改了函數的返回類型。本文將演示一個常見問題及解決方案。
問題: Pylance無法正確識別經過自定義裝飾器修飾后的函數返回類型。例如,一個裝飾器修改了函數的返回類型,但Pylance仍然顯示原始函數的返回類型,導致類型警告。
示例代碼:
def execute(func): def inner_wrapper(*args, **kwargs) -> result[any]: # Pylance問題所在 with session.begin() as session: result = session.execute(func(*args, **kwargs)) return result return inner_wrapper @execute def query_data_source(start_id: int = 1, max_results_amount: int = 10) -> select: stmt = select( datasource.id, datasource.name, datasource.source_url, datasource.author, datasource.description, datasource.cover_image_url, datasource.start_date, datasource.end_date, ).where(datasource.id >= start_id).limit(max_results_amount).order_by(datasource.id) return stmt
query_data_source 函數實際返回 result[any] 類型,但Pylance 仍然將其識別為 select 類型,引發類型警告。
立即學習“Python免費學習筆記(深入)”;
解決方案: 利用 typing.Callable 更精確地聲明裝飾器的返回類型,從而幫助Pylance 正確理解裝飾器的行為。
修改后的代碼:
from typing import Callable, Any def execute(func: Callable[..., Any]) -> Callable[..., Result[Any]]: # 使用typing.Callable def inner_wrapper(*args, **kwargs) -> Result[Any]: with Session.begin() as session: result = session.execute(func(*args, **kwargs)) return result return inner_wrapper @execute def query_data_source(start_id: int = 1, max_results_amount: int = 10) -> select: stmt = select( datasource.id, datasource.name, datasource.source_url, datasource.author, datasource.description, datasource.cover_image_url, datasource.start_date, datasource.end_date, ).where(datasource.id >= start_id).limit(max_results_amount).order_by(datasource.id) return stmt
通過在 execute 裝飾器中使用 Callable[…, Result[Any]] 作為返回類型提示,Pylance 可以準確推斷出 query_data_source 函數的實際返回類型,從而消除類型警告。 … 表示參數個數可變,Any 表示參數類型可變。 確保 Result 和 select 類型已正確定義。
此方法有效地解決了 Pylance 在處理自定義裝飾器時對返回類型推斷的局限性,從而提高代碼的可讀性和可維護性。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END