将 YAML 文件转换为 Python JSON 对象

Posted

技术标签:

【中文标题】将 YAML 文件转换为 Python JSON 对象【英文标题】:Converting a YAML file to Python JSON object 【发布时间】:2018-11-23 13:53:26 【问题描述】:

如何加载 YAML 文件并将其转换为 Python JSON 对象?

我的 YAML 文件如下所示:

Section:
    heading: Heading 1
    font: 
        name: Times New Roman
        size: 22
        color_theme: ACCENT_2

SubSection:
    heading: Heading 3
    font:
        name: Times New Roman
        size: 15
        color_theme: ACCENT_2
Paragraph:
    font:
        name: Times New Roman
        size: 11
        color_theme: ACCENT_2
Table:
    style: MediumGrid3-Accent2

【问题讨论】:

【参考方案1】:

你可以使用PyYAML

pip install PyYAML

在 ipython 控制台中:

In [1]: import yaml

In [2]: document = """Section:
   ...:     heading: Heading 1
   ...:     font: 
   ...:         name: Times New Roman
   ...:         size: 22
   ...:         color_theme: ACCENT_2
   ...: 
   ...: SubSection:
   ...:     heading: Heading 3
   ...:     font:
   ...:         name: Times New Roman
   ...:         size: 15
   ...:         color_theme: ACCENT_2
   ...: Paragraph:
   ...:     font:
   ...:         name: Times New Roman
   ...:         size: 11
   ...:         color_theme: ACCENT_2
   ...: Table:
   ...:     style: MediumGrid3-Accent2"""
   ...:     

In [3]: yaml.load(document)
Out[3]: 
'Paragraph': 'font': 'color_theme': 'ACCENT_2',
   'name': 'Times New Roman',
   'size': 11,
 'Section': 'font': 'color_theme': 'ACCENT_2',
   'name': 'Times New Roman',
   'size': 22,
  'heading': 'Heading 1',
 'SubSection': 'font': 'color_theme': 'ACCENT_2',
   'name': 'Times New Roman',
   'size': 15,
  'heading': 'Heading 3',
 'Table': 'style': 'MediumGrid3-Accent2'

【讨论】:

不仅是前面的评论所说的,而且您使用的是 IPython 的控制台,而不是普通的 Python 控制台;) 1) OP 请求的 JSON 在哪里? JSON strings 有双引号。 2) PyYAML 的load() 被记录为不安全,并且没有任何借口可以在此处(或几乎其他任何地方)使用它来代替safe_load()。 3) 你没有提到 PyYAML 只支持旧的 2009 年之前的 YAML 1.1 规范。 1.你对 Python 中的 JSON 类型是什么意思,也许你可以帮我读一下。是字典。其他 cmets 作为您的回答很好也很有趣,谢谢。【参考方案2】:

PyYAML 库就是为此而设计的

pip install pyyaml
import yaml
import json
with open("example.yaml", 'r') as yaml_in, open("example.json", "w") as json_out:
    yaml_object = yaml.safe_load(yaml_in) # yaml_object will be a list or a dict
    json.dump(yaml_object, json_out)

注意:PyYAML 仅支持 2009 年之前的 YAML 1.1 规范。如果需要 YAML 1.2,ruamel.yaml 是一个选项。

pip install ruamel.yaml

【讨论】:

我同意,这是一个更明确的答案。我会在这里留下我的答案,因为它包括文件处理部分,尽管它没有被特别要求,因为它可能经常需要。 当你提到其他答案被清除时,我复制了 pip install 部分,谢谢。 PyYAML 的 load() 被证明是不安全的,并且没有任何借口可以在此处(或几乎其他任何地方)使用它来代替 safe_load()。您没有提到 PyYAML 仅支持旧的 2009 年之前的 YAML 1.1 规范。 我不知道,我会把它包含在答案中,谢谢。 跟踪 PyYaml 规范:github.com/yaml/pyyaml/issues/116【参考方案3】:

没有像 Python JSON 对象这样的东西。 JSON 是一种独立于语言的文件格式,其根源在于 javascript,并受到多种语言的支持。

如果您的 YAML 文档遵循旧的 1.1 标准,即 2009 年之前的标准,您可以按照其他一些答案的建议使用 PyYAML。

如果它使用更新的 YAML 1.2 规范,这使 YAML 成为 JSON 的超集,您应该使用 ruamel.yaml(免责声明:我是该包的作者,它是 PyYAML 的一个分支)。

import ruamel.yaml
import json

in_file = 'input.yaml'
out_file = 'output.json'

yaml = ruamel.yaml.YAML(typ='safe')
with open(in_file) as fpi:
    data = yaml.load(fpi)
with open(out_file, 'w') as fpo:
    json.dump(data, fpo, indent=2)

生成output.json:


  "Section": 
    "heading": "Heading 1",
    "font": 
      "name": "Times New Roman",
      "size": 22,
      "color_theme": "ACCENT_2"
    
  ,
  "SubSection": 
    "heading": "Heading 3",
    "font": 
      "name": "Times New Roman",
      "size": 15,
      "color_theme": "ACCENT_2"
    
  ,
  "Paragraph": 
    "font": 
      "name": "Times New Roman",
      "size": 11,
      "color_theme": "ACCENT_2"
    
  ,
  "Table": 
    "style": "MediumGrid3-Accent2"
  

ruamel.yaml 除了支持 YAML 1.2 之外,还修复了许多 PyYAML 错误。您还应该注意,如果您始终无法完全控制输入,那么 PyYAML 的 load() 也被记录为不安全的。 PyYAML 还将标量数 021 加载为整数 17 而不是 21 和 converts scalar strings like on, yes, off to boolean 值(分别为 TrueTrueFalse)。

【讨论】:

感谢分享。大量的帮助! 感谢您开发现代和更高质量的软件包。 PyYAML 不是废弃软件,最新版本 (5.4.1) 是 2021 年 1 月。您是提交 PR 却被拒绝,还是分叉而不尝试修复原始版本? @Dave PRs 没有被拒绝,几年都没有答案,然后项目被移动并打开 PRs 和问题在这个过程中下降我没有看到任何 IMO 保证主要版本自 3.12 以来的数字变化,PyYAML 仍然在 2009 年被取代的标准上。 谢谢。出于某种原因,我无法使用 pip 安装 pyyaml ......看起来它工作正常,但无法在任何脚本中导入它......但是 ruamel.yaml 工作正常并且可以导入它,因此可以这样;) - PS:我真的希望您没有在名称中使用一个点来命名它...与 IDE 混为一谈没有结束 @AustEcon 您使用的是什么 IDE,无法处理 Python 命名空间?也许你应该在 *** 上发布一个问题,可能有一个解决方法。 (本人在Linux下使用kakoune及其LSP开发,没有任何问题)。【参考方案4】:

在python3中你可以使用pyyaml。

$ pip3 install pyyaml

然后你加载你的 yaml 文件并将其转储到 json 中:

import yaml, json

with open('./file.yaml') as f:
    print(json.dumps(yaml.load(f)))

输出:

"Section": null, "heading": "Heading 1", "font": "name": "Times New Roman", "size": 22, "color_theme": "ACCENT_2", "SubSection": "heading": "Heading 3", "font": "name": "Times New Roman", "size": 15, "color_theme": "ACCENT_2", "Paragraph": "font": "name": "Times New Roman", "size": 11, "color_theme": "ACCENT_2", "Table": "style": "MediumGrid3-Accent2"

【讨论】:

PyYAML 的 load() 被证明是不安全的,并且没有任何借口可以在此处(或几乎其他任何地方)使用它来代替 safe_load()。像许多其他人一样,您没有提到 PyYAML 仅支持旧的 2009 年之前的 YAML 1.1 规范。【参考方案5】:
import yaml
import json   

def create_json():
    with open("document.yaml","r") as yaml_doc:
        yaml_to_dict=yaml.load(yaml_doc,Loader=yaml.FullLoader)
        # write this dictionary as json object 
        with open("document.json","w") as json_doc:
            json.dump(yaml_to_dict,json_doc)
    print("yaml file is converted to json")

你需要安装pip install pyyaml

【讨论】:

以上是关于将 YAML 文件转换为 Python JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

从命令行将 Swagger YAML 文件转换为 JSON

如何在 bash 中将 json 响应转换为 yaml

将 YAML 转换为 JSON 时出错,未找到预期的密钥 kubernetes

如何使用 Java 库将标记的 YAML 对象转换为 JSON 对象?

如何将php json数组转换为yaml

使用 PyYaml 将 Python 字典转换为 yaml 文档