Utils
petsard.utils
PETsARD 系統的核心工具函數,提供外部模組載入和其他常用操作的基本工具。
設計概述
Utils 模組提供 PETsARD 系統中使用的通用工具函數。它遵循關注點分離的原則,提供核心功能而不包含特定領域的邏輯。
核心原則
- 通用性: 提供通用的工具函數,不包含特定領域的邏輯
- 獨立性: 不依賴其他 PETsARD 模組,作為基礎工具層
- 可擴展性: 支援透過參數自定義行為
- 錯誤處理: 提供完善的錯誤捕獲和報告機制
函數
load_external_module()
load_external_module(module_path, class_name, logger, required_methods=None, search_paths=None)
載入外部 Python 模組並返回模組實例和類別。
參數
module_path
(str): 外部模組的路徑 (相對或絕對)class_name
(str): 要從模組載入的類別名稱logger
(logging.Logger): 用於記錄訊息的日誌記錄器required_methods
(dict[str, list[str]], 可選): 方法名稱對應必需參數名稱的字典search_paths
(list[str], 可選): 解析模組路徑時嘗試的額外搜索路徑
回傳值
Tuple[Any, Type]
: 包含模組實例和類別的元組
例外
FileNotFoundError
: 如果模組檔案不存在ConfigError
: 如果無法載入模組或模組不包含指定的類別
使用範例
基本使用
import logging
from petsard.utils import load_external_module
# 設置日誌記錄器
logger = logging.getLogger(__name__)
# 從當前目錄載入模組
try:
module, cls = load_external_module(
module_path='my_module.py',
class_name='MyClass',
logger=logger
)
instance = cls(config={'param': 'value'})
except Exception as e:
logger.error(f"載入失敗: {e}")
使用自定義搜索路徑的進階用法
import logging
from petsard.utils import load_external_module
logger = logging.getLogger(__name__)
# 自定義搜索路徑
search_paths = [
'/path/to/custom/modules',
'./external_modules',
'../shared_modules'
]
try:
module, cls = load_external_module(
module_path='advanced_module.py',
class_name='AdvancedClass',
logger=logger,
search_paths=search_paths,
required_methods={
'__init__': ['config'],
'process': ['data'],
'validate': []
}
)
instance = cls(config={'advanced': True})
except Exception as e:
logger.error(f"載入失敗: {e}")
路徑解析邏輯
預設搜索順序
- 直接路徑: 直接使用提供的 module_path
- 當前工作目錄: os.path.join(cwd, module_path)
- 自定義路徑: search_paths 參數中的所有路徑
解析規則
- 如果是絕對路徑且檔案存在,直接使用
- 按順序嘗試每個搜索路徑
- 找到第一個存在的檔案即停止
- 如果都找不到,拋出 FileNotFoundError
架構優勢
1. 關注點分離
- 核心功能: 專注於通用的模組載入邏輯
- 無特定領域邏輯: 不包含 demo 或其他特定用途的硬編碼
2. 可擴展性
- 參數化設計: 透過參數控制行為
- 自定義搜索路徑: 支援任意的搜索路徑配置
- 可選方法驗證: 可選的介面驗證功能
3. 錯誤處理
- 詳細錯誤信息: 提供具體的失敗原因
- 搜索路徑報告: 列出所有嘗試的路徑
- 分層錯誤處理: 不同類型的錯誤有不同的處理
4. 日誌記錄
- 調試信息: 詳細的調試日誌
- 錯誤記錄: 完整的錯誤日誌
- 進度追蹤: 載入過程的進度記錄
與 Demo Utils 的協作
職責分工
- petsard.utils: 提供通用的核心功能
- demo.utils: 提供 demo 特定的搜索路徑和邏輯
協作模式
# demo.utils.load_demo_module 的實現
def load_demo_module(module_path, class_name, logger, required_methods=None):
# 生成 demo 特定的搜索路徑
demo_search_paths = _get_demo_search_paths(module_path)
# 使用核心功能進行載入
return load_external_module(
module_path=module_path,
class_name=class_name,
logger=logger,
required_methods=required_methods,
search_paths=demo_search_paths
)
效益
- 模組化設計: 清晰的職責分離,核心功能與特定用途分開
- 可重用性: 通用的工具函數可被多個模組使用
- 可維護性: 集中的工具函數易於維護和更新
- 可測試性: 獨立的函數易於單元測試
- 可擴展性: 參數化設計支援多種使用場景
這個設計確保 Utils 模組提供穩定、通用的工具支援,同時保持架構的清潔和模組化原則。