为什么要进行YAML与JSON转换?

在微服务架构和DevOps实践中,我们常遇到:

  • 配置管理(YAML更适合人类编辑)
  • API数据交互(JSON是Web标准格式)
  • 多云部署(不同平台格式要求不同)
  • 数据持久化(JSON更易压缩存储)

Python实现YAML与JSON高效互转

1.1 准备工作

# conda 环境
pip install pyyaml

YAML转JSON完整流程

import yaml
import json
import sys
import os

def yaml_to_json(yaml_str):
    try:
        data = yaml.safe_load(yaml_str)
        return json.dumps(data, indent=2, ensure_ascii=False, default=str)
    except yaml.YAMLError as e:
        print(f"YAML解析错误: {e.problem} {e.context}")
    except Exception as e:
        print(f"未知错误: {str(e)}")

if __name__ == "__main__":
    if len(sys.argv) > 1:
        yaml_file = sys.argv[1]
        if not os.path.isfile(yaml_file):
            print(f"文件不存在: {yaml_file}")
            sys.exit(1)

        with open(yaml_file, 'r', encoding='utf-8') as f:
            yaml_content = f.read()
        
        json_output = yaml_to_json(yaml_content)
        json_file = os.path.splitext(yaml_file)[0] + ".json"
        
        with open(json_file, 'w', encoding='utf-8') as f:
            f.write(json_output)
        
        print(f"已成功将 YAML 转换为 JSON,输出文件: {json_file}")
    else:
        # 默认测试数据
        yaml_content = """
param:
  Author: Yanzhi
  Email: [email protected]
  Sample: RNA
  Number: 12
  Source: Lab

data:
  indexdir: /index/
  filedir: /rawdata
  filenames:
    - MERS_set2_0h_1
    - MERS_set2_0h_2
    - MERS_set2_16h_1
    - MERS_set2_16h_2
    - MERS_set2_48h_1
    - MERS_set2_48h_2
    - SARS_0h_1
    - SARS_0h_2
    - SARS_16h_1
    - SARS_16h_2
    - SARS_48h_1
    - SARS_48h_2
"""
        print(yaml_to_json(yaml_content))
{
  "param": {
    "Author": "Yanzhi",
    "Email": "[email protected]",
    "Sample": "RNA",
    "Number": 12,
    "Source": "Lab"
  },
  "data": {
    "indexdir": "/index/",
    "filedir": "/rawdata",
    "filenames": [
      "MERS_set2_0h_1",
      "MERS_set2_0h_2",
      "MERS_set2_16h_1",
      "MERS_set2_16h_2",
      "MERS_set2_48h_1",
      "MERS_set2_48h_2",
      "SARS_0h_1",
      "SARS_0h_2",
      "SARS_16h_1",
      "SARS_16h_2",
      "SARS_48h_1",
      "SARS_48h_2"
    ]
  }
}

关键特性说明:

python yaml_to_json.py config.yaml

JSON转YAML高级用法

import json
import yaml
import sys
import os

def json_to_yaml(json_str):
    try:
        data = json.loads(json_str)
        return yaml.dump(data, allow_unicode=True, sort_keys=False)
    except json.JSONDecodeError as e:
        print(f"JSON解析错误: {e.msg} at line {e.lineno} column {e.colno}")
    except Exception as e:
        print(f"未知错误: {str(e)}")

if __name__ == "__main__":
    if len(sys.argv) > 1:
        json_file = sys.argv[1]
        if not os.path.isfile(json_file):
            print(f"文件不存在: {json_file}")
            sys.exit(1)

        with open(json_file, 'r', encoding='utf-8') as f:
            json_content = f.read()
        
        yaml_output = json_to_yaml(json_content)
        yaml_file = os.path.splitext(json_file)[0] + ".yaml"

        with open(yaml_file, 'w', encoding='utf-8') as f:
            f.write(yaml_output)
        
        print(f"已成功将 JSON 转换为 YAML,输出文件: {yaml_file}")
    else:
        # 测试 JSON 数据(与前面 YAML 测试数据结构一致)
        json_content = """
{
  "param": {
    "Author": "Yanzhi",
    "Email": "[email protected]",
    "Sample": "RNA",
    "Number": 12,
    "Source": "Lab"
  },
  "data": {
    "indexdir": "/index/",
    "filedir": "/rawdata",
    "filenames": [
      "MERS_set2_0h_1",
      "MERS_set2_0h_2",
      "MERS_set2_16h_1",
      "MERS_set2_16h_2",
      "MERS_set2_48h_1",
      "MERS_set2_48h_2",
      "SARS_0h_1",
      "SARS_0h_2",
      "SARS_16h_1",
      "SARS_16h_2",
      "SARS_48h_1",
      "SARS_48h_2"
    ]
  }
}
"""
        print(json_to_yaml(json_content))
param:
  Author: Yanzhi
  Email: [email protected]
  Sample: RNA
  Number: 12
  Source: Lab
data:
  indexdir: /index/
  filedir: /rawdata
  filenames:
  - MERS_set2_0h_1
  - MERS_set2_0h_2
  - MERS_set2_16h_1
  - MERS_set2_16h_2
  - MERS_set2_48h_1
  - MERS_set2_48h_2
  - SARS_0h_1
  - SARS_0h_2
  - SARS_16h_1
  - SARS_16h_2
  - SARS_48h_1
  - SARS_48h_2

JavaScript浏览器端解决方案

浏览器端实现

json to yaml

  <script>
    function convertToYaml() {
      const input = document.getElementById("jsonInput").value;
      const output = document.getElementById("yamlOutput");
      try {
        const obj = JSON.parse(input);
        const yaml = jsyaml.dump(obj, { sortKeys: false });
        output.textContent = yaml;
      } catch (e) {
        output.textContent = "❌ JSON 解析错误: " + e.message;
      }
    }
  </script>

yaml to json

    function convertToJson() {
      const yamlText = document.getElementById("yamlInput").value;
      const output = document.getElementById("outputArea");
      try {
        const obj = jsyaml.load(yamlText);
        const json = JSON.stringify(obj, null, 2);
        output.textContent = json;
      } catch (e) {
        output.textContent = "❌ YAML 解析错误: " + e.message;
      }
    }

在线版本

根据 javascript 版本生成 html, 在线yaml json

核心差异与最佳实践

格式对比

特性 YAML JSON
注释 支持 # 注释 不支持
数据类型 扩展类型(日期、正则) 基础类型
可读性 中等
文件大小 较小 较大
  • 需要人工编辑? → 选 YAML
  • 需要严格 Schema? → 选 JSON
  • 需要跨平台传输? → 选 JSON
  • 需要版本控制? → 选 YAML(差异更清晰)

常见问题解决方案

特殊字符转义: JSON中需要转义双引号,YAML支持单双引号混合使用 日期格式处理:

# Python自定义转换器
class SafeDateYamlLoader(yaml.SafeLoader):
    pass

def timestamp_constructor(loader, node):
    return datetime.fromisoformat(loader.construct_scalar(node))

SafeDateYamlLoader.add_constructor('!datetime', timestamp_constructor)

大文件处理技巧: 分块读取转换

结语

通过本文的详细讲解,相信您已经掌握了:

  • 两种语言实现格式转换的核心方法
  • 不同场景下的最佳实践选择
  • 常见问题的应对策略

实际应用建议:

  • 配置管理优先使用 YAML
  • API 交互推荐 JSON 格式
  • 复杂数据类型注意兼容性

掌握格式转换技能将显著提升您的开发效率,建议结合 获得ChatGPT API 进行自动化脚本开发,构建智能化的数据处理工作流。