YAML别名拼接路径遇ScannerError,Python读取问题求助
YAML别名拼接路径触发ScannerError的解决方法
问题背景
我有一份包含数百个长期实验结果文件路径的YAML数据,所有结果存于不同目录但共享同一根目录。为避免重复路径,我定义了根目录别名并尝试在路径中拼接,但使用Python的yaml.safe_load读取时触发ScannerError:
YAML代码(DEMO.yaml)
define: &root '/Users/SAL/Documents/Projects/FORD_CELLS/' test1 : *root+'test1/result.csv' test2 : *root+'test2/result.csv'
Python读取代码
import yaml import pandas as pd exp_info = yaml.safe_load(open('DEMO.yaml')) exp_info['test2']
错误信息
ScannerError: while scanning an alias expected alphabetic or numeric character, but found '+'
错误原因
YAML的别名(*root)语法仅支持直接引用锚点值,不支持在YAML层面直接和字符串进行拼接操作。当解析器遇到*root后的+号时,不符合别名的语法规则,因此抛出ScannerError。
解决方案
方案1:Python读取后统一拼接路径(推荐)
修改YAML文件,仅存储相对路径,在Python代码中读取根目录后批量拼接,简单直接且无语法风险:
修改后的DEMO.yaml:
root: '/Users/SAL/Documents/Projects/FORD_CELLS/' test1: 'test1/result.csv' test2: 'test2/result.csv'
Python代码:
import yaml exp_info = yaml.safe_load(open('DEMO.yaml')) root_path = exp_info.pop('root') # 批量处理所有路径 for key, rel_path in exp_info.items(): exp_info[key] = root_path + rel_path print(exp_info['test2'])
方案2:自定义YAML标签实现拼接
如果希望在YAML层面完成路径拼接,可以自定义!join标签并注册构造器:
修改后的DEMO.yaml:
root: &root '/Users/SAL/Documents/Projects/FORD_CELLS/' test1: !join [*root, 'test1/result.csv'] test2: !join [*root, 'test2/result.csv']
Python代码:
import yaml # 定义拼接逻辑的构造器 def join_constructor(loader, node): parts = loader.construct_sequence(node) return ''.join(parts) # 注册自定义标签到safe_load yaml.add_constructor('!join', join_constructor) exp_info = yaml.safe_load(open('DEMO.yaml')) print(exp_info['test2'])
方案3:折叠标量(不推荐)
如果不需要动态复用根目录,可使用YAML折叠标量格式化路径,但无法避免重复编写根路径,不适用于大量文件的场景:
root: '/Users/SAL/Documents/Projects/FORD_CELLS/' test1: >- /Users/SAL/Documents/Projects/FORD_CELLS/test1/result.csv test2: >- /Users/SAL/Documents/Projects/FORD_CELLS/test2/result.csv
内容的提问来源于stack exchange,提问作者Yash
相关产品推荐
相关产品推荐

