You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:05:19