Python如何在解析 YAML 文件时保留每个条目的原始行号信息
这样读取yaml文件后,报错信息显示的是item的编号,但是如果想要显示这个item在yaml文件中的原始行号:
with open(yaml_path, 'r', encoding='utf-8') as file:data = yaml.safe_load(file)if not isinstance(data, list):raise ValueError("YAML 数据格式错误:应为条目列表")errors = []
terms_seen = set()for idx, entry in enumerate(data, start=2):# 从2开始,行号计算标题行context = f"Entry {idx} ('{entry.get('Term', 'Unknown')}')"
为了在解析 YAML 文件时保留每个条目的原始行号信息,可以使用 ruamel.yaml
替代 PyYAML
(yaml.safe_load
就是它的一部分)。ruamel.yaml
支持保留注释和行号,是专门为这种需求设计的。
✅ 目标:
你希望在处理 entry
时能知道它在原始 YAML 文件中的行号,以便在报错时提示更直观。
🔧 解决方案:
使用 ruamel.yaml
加载并追踪每条数据的行号:
from ruamel.yaml import YAML
from ruamel.yaml.compat import StringIOyaml = YAML()
yaml.preserve_quotes = True # 可选:保持原始引号with open(yaml_path, 'r', encoding='utf-8') as f:content = f.read()data = yaml.load(content)# 确保数据是列表形式
if not isinstance(data, list):raise ValueError("YAML 数据格式错误:应为条目列表")errors = []
terms_seen = set()for entry in data:# 获取该 entry 的行号(+1,因为 ruamel 使用0-based)line_no = entry.lc.line + 1term = entry.get('Term', 'Unknown')context = f"Line {line_no} ('{term}')"# 示例:检测重复术语if term in terms_seen:errors.append(f"{context} - Term 重复")else:terms_seen.add(term)# 打印错误
for err in errors:print(err)
📌 示例 YAML 内容
- Term: appleDefinition: A fruit
- Term: bananaDefinition: Another fruit
- Term: appleDefinition: Duplicate
输出:
Line 5 ('apple') - Term 重复
📦 安装 ruamel.yaml
如果你未安装 ruamel.yaml
,可以通过 pip 安装:
pip install ruamel.yaml