使用ruamel.yaml时如何保留!!timestamp及其他标签?
解决YAML修改后丢失
~和!!timestamp标签的问题 方案一:使用ruamel.yaml保留原格式(推荐)
ruamel.yaml专门设计用于保留YAML的原有结构、标签和注释,比PyYAML更适合这类场景。
安装ruamel.yaml:
pip install ruamel.yaml
示例代码:
from ruamel.yaml import YAML # 初始化YAML对象,保留原有格式细节 yaml = YAML() yaml.preserve_quotes = True # 加载原YAML文件 with open('input.yaml', 'r', encoding='utf-8') as f: data = yaml.load(f) # 仅修改你需要的独立组内容 # 示例:data['target_group'] = {'new_key': 'new_value'} # 写入修改后的文件,自动保留原标签和格式 with open('output.yaml', 'w', encoding='utf-8') as f: yaml.dump(data, f)
这个方案无需额外配置,加载和dump时会自动保留~(null)和!!timestamp标签,同时维持原有的缩进、键顺序甚至注释。
方案二:自定义PyYAML的表示器
如果坚持使用PyYAML,需要为None和datetime类型自定义输出格式,强制生成对应的标签:
import yaml from datetime import datetime # 自定义None的输出格式,替换为~ def represent_none(dumper, data): return dumper.represent_scalar('tag:yaml.org,2002:null', '~') # 自定义datetime的输出格式,添加!!timestamp标签 def represent_timestamp(dumper, data): return dumper.represent_scalar('tag:yaml.org,2002:timestamp', data.strftime('%Y-%m-%d')) # 注册自定义表示器 yaml.add_representer(type(None), represent_none) yaml.add_representer(datetime, represent_timestamp) # 加载原文件 with open('input.yaml', 'r', encoding='utf-8') as f: data = yaml.load(f, Loader=yaml.FullLoader) # 仅修改目标组内容 # 示例:data['target_group'] = {'new_key': 'new_value'} # 写入文件,关闭排序键以保留原顺序 with open('output.yaml', 'w', encoding='utf-8') as f: yaml.dump(data, f, default_flow_style=False, sort_keys=False)
注意设置sort_keys=False,避免PyYAML自动排序键打乱原文件结构。
关于“只加载需要修改的组”的思路
两种方案都支持仅操作目标组数据——只要你在代码中只修改特定的组(比如data['your_target_group']),其余部分会被原样保留(ruamel.yaml更彻底,连注释都能完整保留),完全符合你“最小化影响其他内容”的需求。
内容的提问来源于stack exchange,提问作者Cooler Mann
相关产品推荐
相关产品推荐

