如何在Python中解析YAML文件

How can I parse a YAML file in Python

如何在python中解析yaml文件?


不依赖C头的最简单、最纯粹的方法是pyyaml(文档):

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python

import yaml

with open("example.yaml", 'r') as stream:
    try:
        print(yaml.safe_load(stream))
    except yaml.YAMLError as exc:
        print(exc)

就是这样。一个普通的yaml.load()函数也存在,但除非您明确需要提供任意对象序列化/反序列化,以避免引入任意代码执行的可能性,否则应始终首选yaml.safe_load()

注意,pyyaml项目支持通过yaml 1.1规范升级的版本。如果需要yaml 1.2规范支持,请参阅本答案中所述的ruamel.yaml。


使用python 2+3(和unicode)读取和写入yaml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -*- coding: utf-8 -*-
import yaml
import io

# Define data
data = {'a list': [1, 42, 3.141, 1337, 'help', u'€'],
        'a string': 'bla',
        'another dict': {'foo': 'bar',
                         'key': 'value',
                         'the answer': 42}}

# Write YAML file
with io.open('data.yaml', 'w', encoding='utf8') as outfile:
    yaml.dump(data, outfile, default_flow_style=False, allow_unicode=True)

# Read YAML file
with open("data.yaml", 'r') as stream:
    data_loaded = yaml.safe_load(stream)

print(data == data_loaded)

创建了yaml文件

1
2
3
4
5
6
7
8
9
10
11
12
a list:
- 1
- 42
- 3.141
- 1337
- help
- €
a string: bla
another dict:
  foo: bar
  key: value
  the answer: 42

通用文件结尾

.yml.yaml

选择

  • csv:超简单格式(读写)
  • JSON:很适合编写人类可读的数据;非常常用(读写)
  • yaml:yaml是json的超集,但更容易阅读(读写,比较json和yaml)
  • pickle:python序列化格式(读写)
  • messagepack(python包):更紧凑的表示形式(读写)
  • HDF5(python包):很适合矩阵(读写)
  • XML:也存在*叹息*(读写)

对于您的应用程序,以下内容可能很重要:

  • 其他编程语言支持
  • 读写能力
  • 紧密度(文件大小)

另请参见:数据序列化格式的比较

如果您想寻找一种生成配置文件的方法,那么您可能需要阅读我在python中的简短文章配置文件。


如果您的yaml符合yaml 1.2规范(2009年发布),那么您应该使用ruamel.yaml(免责声明:我是该包的作者)。它本质上是pyyaml的超集,支持大多数yaml 1.1(从2005年开始)。

如果你想在往返旅行时保留你的评论,你当然应该使用ruamel.yaml。

升级@jon的示例很简单:

1
2
3
4
5
6
7
import ruamel.yaml as yaml

with open("example.yaml") as stream:
    try:
        print(yaml.safe_load(stream))
    except yaml.YAMLError as exc:
        print(exc)

使用safe_load(),除非您真正能够完全控制输入,否则需要它(很少是这种情况),并知道您在做什么。

如果使用pathlib Path来操作文件,则最好使用新的api ruamel.yaml提供:

1
2
3
4
5
6
from ruamel.yaml import YAML
from pathlib import Path

path = Path('example.yaml')
yaml = YAML(typ='safe')
data = yaml.load(path)

导入yaml模块并将文件加载到名为"my_dict"的字典中:

1
2
import yaml
my_dict = yaml.load(open('filename'))

这就是你所需要的。现在整个yaml文件都在"我的字典"中。


例子:

默认值

1
url: https://www.google.com

环境.Py

1
2
3
4
from ruamel import yaml

data = yaml.safe_load(open('defaults.yaml'))
data['url']

我用Ruamel.yaml。这里有详细信息和辩论。

1
2
3
4
from ruamel import yaml

with open(filename, 'r') as fp:
    read_data = yaml.load(fp)

ruamel.yaml的使用与pyyaml的旧用法兼容(有一些简单的可解决的问题),如链接I所述,使用

1
from ruamel import yaml

而不是

1
import yaml

它可以解决你的大部分问题。

编辑:pyyaml并没有像原来那样死,它只是被保存在一个不同的地方。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python

import sys
import yaml

def main(argv):

    with open(argv[0]) as stream:
        try:
            #print(yaml.load(stream))
            return 0
        except yaml.YAMLError as exc:
            print(exc)
            return 1

if __name__ =="__main__":
    sys.exit(main(sys.argv[1:]))