Files
feifei.xu f188055228 清理无用代码、合并工具链、修复注释与日志问题
- 删除破损文件: main.py/main.ui/main_ui.py
- 删除 runtime_hook.py(归宿主维护),清除 tools/ 目录
- 合并 export_runtime/pack_zip/verify_companions 到 build_pyd.py
- 修复注释: docstring 参数与实际签名不一致、过时引用、拼写错误
- 修复日志: 消除静默吞异常、删冗余 log+raise、补缺失日志
- 精简 .gitignore
2026-07-21 18:14:34 +08:00

175 lines
5.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""MIL SDK 核心数据模型"""
import os
import json
import logging
from dataclasses import dataclass, field, fields
from typing import Any
logger = logging.getLogger(__name__)
@dataclass
class Config():
"""MIL SDK 全局配置
承载测试工程相关的全局开关与路径信息,是 UI 层与 core 层之间的
配置传输载体。序列化使用 JSON 文件持久化。
Attributes:
path: 配置文件路径(JSON 文件)
DataPath: 仿真数据目录
FilePath: 当前打开的 Excel 文件路径
AddTimeEn: 用例步骤时间是否按累加方式记录
GeratePath: 是否为生成的用例另存新文件
CurrProject: 当前工程名称
ItemConfigs: 各模块/用例项的细粒度配置
"""
path:str
DataPath:str = ""
FilePath:str = ""
AddTimeEn:bool = True
GeratePath:bool = True
CurrProject:str = ""
# dict 是可变类型,必须用 default_factory 显式实例化,避免多个 Config 共享同一对象
ItemConfigs: dict = field(default_factory=dict)
def check_path(self):
return os.path.exists(self.path)
def to_dict(self):
"""将 Config 实例序列化为 dict,便于写入 JSON 文件。"""
return {
"DataPath":self.DataPath,
"FilePath":self.FilePath,
"AddTimeEn":self.AddTimeEn,
"GeratePath":self.GeratePath,
"CurrProject":self.CurrProject,
"ItemConfigs":self.ItemConfigs,
}
def load_config(self) -> "Config":
"""从 self.path 指定的 JSON 文件读取配置并填充到当前实例的各个字段。
解析规则:
- JSON 中存在的字段会被回写到 Config 的对应字段;
- JSON 中缺失的字段保持当前 Config 实例的默认值;
- JSON 中多余字段被忽略(向前兼容:增加字段不会破坏老配置)。
Returns:
self:填充后的 Config 实例,便于链式调用。
Raises:
FileNotFoundError: 配置文件不存在。
json.JSONDecodeError: 文件内容不是合法 JSON。
"""
try:
# 以 UTF-8 读取 JSON,避免 Windows 默认编码带来的乱码问题
with open(self.path, 'r', encoding='utf-8') as f:
raw = json.load(f)
except FileNotFoundError:
# 显式记录并重抛,遵循"错误必须显式处理,禁止静默失败"
logger.error(f"配置文件{self.path}未找到")
raise
if not isinstance(raw, dict):
# 文件不合法(非 dict 根节点)→ 用一个空 dict 填充,保持实例可用
raw = {}
# 用反射取出本类已声明的字段名白名单,避免 JSON 脏字段污染
allowed = {f.name for f in fields(self.__class__)}
for key, value in raw.items():
if key in allowed:
setattr(self, key, value)
return self
def save_config(self):
"""将当前配置以 JSON 格式写入 self.path 指定的文件。
Raises:
Exception: 写入失败时记录日志并原样抛出异常。
"""
try:
with open(self.path,'w',encoding='utf-8') as f:
json.dump(self.to_dict(), f, indent=4, ensure_ascii=False)
except Exception as e:
logger.error(f"配置文件{self.path}写入失败: {e}")
raise
@dataclass
class DataLog:
"""仿真数据日志记录
Attributes:
time: 时间戳(秒)
value: 信号值(字符串形式,写入 Excel 时按内容推断 int/str 类型)
"""
time: float = 0.0
value: str = ""
@dataclass
class SignalData:
"""信号数据封装
描述 Excel 中某一列信号的完整信息:
- 所在列号(column
- 列上方的属性行(attributes,例如 Signal Name / BlockPath 等)
- 时间-值采样序列(datalog
Attributes:
column: 信号在 Excel 工作表中的列索引(1-based
attributes: 列上方各属性行(行号 -> 文本)的字典映射
datalog: 时间戳-数值采样点列表
"""
column: int = 0
attributes: dict[str, str] = field(default_factory=dict)
datalog: list[DataLog] = field(default_factory=list)
def to_dict(self) -> dict[str, Any]:
"""将 SignalData 转为 dict,便于跨层传输与持久化。
Returns:
包含 column、attributes、datalog 字段的字典。
"""
return {
"column": self.column,
"attributes": self.attributes,
"datalog": self.datalog
}
@dataclass
class ExcelDataResult:
"""Excel 数据读取结果封装
提供对 Excel 数据的类型安全访问,隐藏内部实现细节
Attributes:
sheet_name: 工作表名称
source_row: Source: Input 所在行号
signals: 信号名称到信号数据的映射
"""
sheet_name: str = "Scenario1"
source_row: int = 0
signals: dict[str, SignalData] = field(default_factory=dict)
def get_signal(self, name: str) -> SignalData | None:
"""获取指定信号的数据
Args:
name: 信号名称
Returns:
信号数据对象,如果不存在返回 None
"""
return self.signals.get(name)
def get_signal_names(self) -> list[str]:
"""获取所有信号名称
Returns:
信号名称列表
"""
return list(self.signals.keys())