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

Python用ruamel.yaml为任意嵌套的指定键值添加双引号

ruamel.yaml 如何在dump阶段为指定键的取值强制添加双引号?

需求是:无论嵌套层级多深,只要键名匹配指定列表(比如示例中的grouping),对应取值就用双引号包裹,其余键的取值保持默认无引号格式。

你已经通过预处理数据、将目标键的取值转为DoubleQuotedScalarString实现了需求,下面给出在dump阶段直接实现的方案:

实现思路

ruamel.yaml的序列化依赖代表器(Representer),我们可以重写字典映射的代表逻辑,在处理每个键值对时判断键是否属于目标列表,若是则将其值转为双引号标量字符串后再序列化,同时递归处理嵌套的字典和列表结构。

代码示例

import sys
from ruamel.yaml import YAML, Representer
from ruamel.yaml.scalarstring import DoubleQuotedScalarString

data = {
    'simple': 'nonquoted',
    'grouping': 'quoted',
    'deep': {
        'simple': 'nonquoted',
        'grouping': 'quoted',
    },
    'list_example': [
        {'grouping': 'in_list'},
        {'simple': 'normal'}
    ]
}

class CustomRepresenter(Representer):
    def __init__(self, *args, quote_keys=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.quote_keys = quote_keys or set()

    def represent_mapping(self, tag, mapping, flow_style=None):
        processed_items = []
        for key, value in mapping.items():
            if key in self.quote_keys and isinstance(value, str):
                # 将目标键的字符串值转为双引号格式
                quoted_val = DoubleQuotedScalarString(value)
                processed_items.append((self.represent_data(key), self.represent_data(quoted_val)))
            else:
                # 递归处理嵌套结构
                if isinstance(value, dict):
                    processed_val = self.represent_mapping(tag, value, flow_style)
                elif isinstance(value, list):
                    processed_val = self.represent_sequence('tag:yaml.org,2002:seq', value, flow_style)
                else:
                    processed_val = self.represent_data(value)
                processed_items.append((self.represent_data(key), processed_val))
        return super().represent_mapping(tag, mapping, flow_style)

def test():
    yaml = YAML()
    yaml.default_flow_style = False
    # 绑定自定义代表器,并指定需要双引号的键
    yaml.Representer = CustomRepresenter
    yaml.representer.quote_keys = {'grouping'}
    yaml.dump(data, sys.stdout)

test()

输出结果

simple: nonquoted
grouping: "quoted"
deep:
  simple: nonquoted
  grouping: "quoted"
list_example:
- grouping: "in_list"
- simple: normal

说明

  • 该方案无需修改原始数据,所有处理都在序列化阶段完成,适合需要保留原始数据结构的场景。
  • 代码中仅处理字符串类型的值,若需要对非字符串值(如数字)也添加双引号,可去掉isinstance(value, str)的判断。
  • 适配你的环境:Python 3.10.13 + ruamel.yaml 0.18.6。

内容的提问来源于stack exchange,提问作者tuck1s

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 17:05:10