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

如何让PyYAML将Python对象序列化为YAML中的原生JSON块?

解决PyYAML将JSON块转为带转义字符串的问题

我之前处理WebService测试用例序列化的时候,也碰到过一模一样的问题——想把Request的fields dict直接转成YAML里原生的JSON兼容结构,不用转义,也不想事后再修改生成的YAML文本。下面给你两个不用后处理的解决方案:

方法一:自定义PyYAML代表器,指定dict输出为JSON流风格

PyYAML默认会把dict序列化为块风格(缩进的键值对),但我们可以给需要特殊处理的dict注册一个自定义代表器,让它直接输出流风格(JSON的花括号格式),这样就完全兼容Postman等工具的复制粘贴需求。

代码示例:

import yaml
from yaml.representer import Representer

# 定义一个标记类,用来区分需要按JSON风格输出的dict
class JSONCompatibleDict(dict):
    pass

# 自定义代表器:将JSONCompatibleDict序列化为流风格的映射(和JSON格式一致)
def represent_json_style_dict(dumper, data):
    # flow_style=True 强制使用花括号的流风格
    return dumper.represent_mapping('tag:yaml.org,2002:map', data, flow_style=True)

# 给PyYAML注册这个代表器
yaml.add_representer(JSONCompatibleDict, represent_json_style_dict)

# 使用示例
# 假设你的Request.fields是这个dict
request_fields = {
    "endpoint": "/api/webservice",
    "method": "POST",
    "headers": {"Content-Type": "application/json"},
    "body": {"user_id": 1001, "payload": "test_data"}
}

# 把fields转换成我们的标记类
json_ready_fields = JSONCompatibleDict(request_fields)

# 构造测试用例结构
test_case = {
    "test_name": "WebService Login Test",
    "request": json_ready_fields,
    "expected_response": {"code": 200, "message": "success"}
}

# 序列化输出
yaml_result = yaml.dump(test_case, default_flow_style=False, sort_keys=False)
print(yaml_result)

输出的YAML会是这样的(request部分直接是JSON兼容的结构):

test_name: WebService Login Test
request: {endpoint: "/api/webservice", method: "POST", headers: {"Content-Type": "application/json"}, body: {"user_id": 1001, "payload": "test_data"}}
expected_response:
  code: 200
  message: success

方法二:用ruamel.yaml简化配置(更省心)

如果你不想写自定义代表器,可以用ruamel.yaml这个增强版的YAML库,它支持更灵活的输出控制,能自动让嵌套的小字典用流风格输出,完全符合你的需求。

首先安装库:

pip install ruamel.yaml

代码示例:

from ruamel.yaml import YAML
import sys

yaml = YAML()
# 设置default_flow_style为None:顶层用块风格,嵌套的小字典自动用流风格(JSON式)
yaml.default_flow_style = None
# 保持键的原有顺序
yaml.sort_keys = False

# 构造测试用例
test_case = {
    "test_name": "WebService Login Test",
    "request": {
        "endpoint": "/api/webservice",
        "method": "POST",
        "headers": {"Content-Type": "application/json"},
        "body": {"user_id": 1001, "payload": "test_data"}
    },
    "expected_response": {"code": 200, "message": "success"}
}

# 输出到控制台(也可以写入文件)
yaml.dump(test_case, sys.stdout)

输出的YAML和方法一的效果一致,而且不需要额外标记dict,非常省心。

原理说明

你之前用json.dumps转成字符串再序列化,PyYAML会把它当成普通字符串处理,所以会加转义符;用|字面量块的话,它还是字符串类型,需要手动解析。而上面的方法是直接让PyYAML把指定的dict序列化为YAML的映射类型,同时用流风格(花括号)输出,这种格式和JSON完全兼容,所以可以直接复制到Postman等工具里使用,完全不需要后处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:04:08