如何用PyYAML加载含!include自定义标签的YAML且转储时保留原格式?
问题原因
你用到的!include : 'params.yml'属于YAML语法中带自定义标签的映射键,默认PyYAML解析后转储会使用显式键语法(带?前缀)输出,就是你得到的不符合预期的格式。
解决方案
通过为!include标签注册自定义构造器和表示器,即可在不实现导入逻辑的前提下,保留该标签的原有格式,完整实现代码如下:
import yaml # 自定义占位类,仅用于存储引用文件路径,无需实现业务逻辑 class IncludeDirective: def __init__(self, path): self.path = path # 构造器:解析!include标签,转换为自定义占位对象 def include_constructor(loader, node): mapping = loader.construct_mapping(node) path = next(iter(mapping.values())) return IncludeDirective(path) # 表示器:转储时将占位对象还原为!include原格式 def include_representer(dumper, data): return dumper.represent_mapping( 'tag:yaml.org,2002:map', {yaml.ScalarNode(tag='!include', value=''): data.path}, flow_style=True ) # 注册构造器和表示器到PyYAML yaml.add_constructor('!include', include_constructor, Loader=yaml.FullLoader) yaml.add_representer(IncludeDirective, include_representer) # 使用示例 if __name__ == '__main__': # 加载原YAML文件 with open('原文件路径.yml', 'r', encoding='utf-8') as f: config = yaml.load(f, Loader=yaml.FullLoader) # 此处可添加你需要的配置修改逻辑 config['_export']['workflow_name'] = 'modified_workflow' # 转储到新文件 with open('新文件路径.yml', 'w', encoding='utf-8') as f: yaml.dump( config, f, sort_keys=False, allow_unicode=True, default_flow_style=False )
注意事项
- 必须添加
sort_keys=False参数,否则PyYAML会自动对配置键排序,打乱原有文件结构 - 如果存在其他同类型自定义标签,可参照上述逻辑新增对应的构造器、表示器即可
- 该方案完全不实现
!include的文件导入逻辑,仅做格式保留,符合你交由第三方工具处理的需求
内容的提问来源于stack exchange,提问作者holec
相关产品推荐
相关产品推荐

