使用Python原生yaml.dump时引号格式变更致Ansible失败,如何保留原引号?
解决方案:用PyYAML保留原始引号格式
PyYAML默认加载YAML时会丢弃字符串的引号元数据,dump时自动选择引号规则,导致你遇到的双引号变单引号、内部单引号被转义的问题。要解决这个,需要自定义Loader和Dumper来记录并复用原始引号格式。
步骤1:自定义带引号记录的Loader
这个Loader会在加载字符串时,保存原始节点的引号样式:
import yaml from yaml.loader import SafeLoader class QuotePreservingLoader(SafeLoader): def construct_scalar(self, node): scalar = super().construct_scalar(node) # 保存原始节点的引号样式到字符串对象的自定义属性 if hasattr(node, 'style'): scalar.__yaml_style__ = node.style return scalar
步骤2:自定义对应的Dumper
这个Dumper会读取字符串对象保存的引号样式,用原始格式输出:
class QuotePreservingDumper(yaml.SafeDumper): def represent_scalar(self, tag, value, style=None): # 优先使用保存的原始引号样式 if hasattr(value, '__yaml_style__'): style = value.__yaml_style__ return super().represent_scalar(tag, value, style)
步骤3:修改你的代码
加载YAML文件时使用自定义Loader
def reload_queue(file_path): with open(file_path, 'r') as f: # 使用自定义Loader加载,保留引号信息 return yaml.load(f, Loader=QuotePreservingLoader)
写入YAML文件时使用自定义Dumper
def update_status(playbook, masterfile): with open(masterfile, 'w') as file: yaml.dump( playbook, file, Dumper=QuotePreservingDumper, # 指定自定义Dumper default_flow_style=False, allow_unicode=True ) # 注意:with语句会自动关闭文件,无需手动调用file.close()
额外说明
- 如果在代码中修改了某个字符串的值,需要手动为新字符串设置
__yaml_style__属性,比如:playbook[0]['vars']['param'] = "{{ new_value }}" playbook[0]['vars']['param'].__yaml_style__ = '"' # 指定用双引号输出 - 此方法基于PyYAML的扩展能力,无需额外依赖,完全符合你不能使用ruamel.yaml的限制。
内容的提问来源于stack exchange,提问作者Anand
相关产品推荐
相关产品推荐

