PyYAML - 在Python中使用YAML
YAML是一种强大的具有可读性的数据序列化标准。在Python中,可以使用PyYAML对YAML格式的文件进行处理,比如:读写配置文件。
PyYAML - 在Python中使用YAML
0 链接
YAML: YAML Ain't Markup Language
What It Is: YAML is a human friendly data serialization standard for all programming languages.
- YAML标准官方网站
PyYAML is a full-featured YAML framework for the Python programming language.
- PyYAML,Python的全功能YAML框架
PyYAML is a YAML parser and emitter for Python.
- PyYAML文档
- 中文、易上手的YAML入门教程
1 YAML
1.1 概述
YAML是一种数据序列化标准,目前看来是最强大的可读型数据序列化标准。
与传统配置文件格式INI(*.ini
)或是JSON(*.json
)相比,YAML(*.yml
)是不仅支持的数据类型丰富,而且还支持注释之类的增强可读性的功能。
INI | JSON | YAML | |
---|---|---|---|
数据类型 | 无* | 有 | 有 |
层次结构 | 一层 | 多层 | 多层 |
支持注释 | 支持 | 不支持 | 支持 |
- INI本身不体现数据类型,需读取时指定数据类型,否则均视为字符串。
1.2 语法规则
1.2.1 基本语法
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用tab,只允许空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
#
表示注释
1.2.2 数据类型
YAML 支持以下几种数据类型:
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
- 纯量(scalars):单个的、不可再分的值
1.3 示例
在官方文档就有示例,不过我更推荐YAML 入门教程 - runoob.com的一个例子,上手快。
我做了一定修改和测试(增加了dict):
1 | # YAML支持注释 |
- 经过我的测试,Python的tuple类型是不认的,只是解析为字符串,不过可以用list。
2 PyYAML
详细的请参考官方文档PyYAML Documentation,以下介绍最简单的操作。
2.1 安装
1 | conda install pyyaml |
或使用pip:
1 | pip install pyyaml |
2.2 使用
2.2.1 safe_load
把上述1.3的示例存入config.yml
中,通过以下代码读取:
1 | import yaml |
一般建议使用
safe_load
,限制使用安全的、核心的YAML功能,否则YAML可以解析各种你想不到的东西,可能会调用Python中的任何东西,例如:直接构建一个类对象。(具体见PyYAML Documentation文档中的解释)非安全函数为
yaml.load(...)
结果是一个`dict
:
1 | {'boolean': [True, False], 'float': [3.14, 685230.15], 'int': [123, 685230], None: {'nodeName': 'node', 'parent': None}, 'string': ['哈哈', 'Hello world', 'newline newline2'], 'dict': {'hp': 13, 'sp': 5}, 'date': [datetime.date(2018, 2, 17)], 'datetime': [datetime.datetime(2018, 2, 17, 15, 2, 31, tzinfo=datetime.timezone(datetime.timedelta(seconds=28800)))]} |
或通过IPython读取:
1 | IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help. |
2.2.2 safe_dump
对于Python对象,也可以导出到文件流中:
1 | import yaml |
- 非安全函数为
yaml.dump(...)
结果在config.dump.yml
中:
1 | age: 20 |
如果未指定输出流,直接导出:
1 | yaml.safe_dump(cfgs) |
结果会直接显示出来,相当于默认为标准IO。
在stream=None
时,源码中根据有无指定encoding
来决定stream
为io.StringIO()
或是io.BytesIO()
。
3 小结
不难看出,YAML格式的文件非常适合作为配置文件:
- 可读性强;
- 自带数据格式:而INI不支持,需要读取时设定读取方法;
- 支持层次结构:而INI不支持;
- 语法简单:基本就是冒号和空格(JSON还需要用大括号包好);
- 和Python兼容很好:一个配置文件读出来就是Python的一个dict。