PyYAML 安装与使用演示

YAML(YAML Ain’t Markup Language)是一种直观的能够被电脑识别的数据序列化格式,既方便被人类阅读,又容易被程序解析。相比 XML 和 JSON ,其语法更简洁直白。YAML 非常适合用来保存数据和程序配置,但可惜 Python 语言标准库中并没有集成解析 YAML 的库(Anaconda 已经集成了)。我们可以通过安装 PyYAML 模块来获得操作 YAML 格式文件的功能。

本文将介绍 PyYAML 库的安装过程。

简介

YAML 是一种人类友好、跨语言易扩展、基于 Unicode 的数据描述语言。PyYAML 是 Python 用于解析和编码 YAML 文件的程序包,由 Kirill Simonov 编写,兼容 Python 2 和 Python 3,代码以 MIT 协议托管在 Github 网站上。

Windows 操作系统

为 Windows 操作系统安装 PyYAML 非常简单。首先需保证计算机已安装 Python 运行环境,然后可以使用以下任意一种方式安装。

使用引导程序

最简单直接的方式是在 PyYAML 的下载页面下载适用于 Windows 系统的对应安装程序,双击安装即可。安装程序将自动检测 Python 环境的安装目录,你只需确认安装目录正确无误。但该方法的缺点是:网站提供的安装程序可能不适用于最新的 Python 版本。比如,截至修改该文章时,该网站还没有提供适配 Python 3.6 的安装引导程序。

使用 Wheel

有些开发者将常用的开源 Python 模块提前编译,并制作成可供 Wheel 程序直接安装的 .whl 文件。你可以从 加州大学尔湾分校(UC Irvine)的页面下载适用的 PyYAML 程序包进行安装。

安装之前必须首先安装 Wheel,在命令行窗口执行:

1
$ pip install wheel

然后就可以使用 pip 安装 .whl 程序包了。以适用于 Python 3.6 的 64 位程序包为例,在该文件所在目录执行:

1
$ pip install PyYAML‑3.12‑cp36‑cp36m‑win_amd64.whl

Linux 操作系统

根据 PyYAML 官方给出的安装方法,下载适用于 Linux 系统的程序包。解压后进入软件包目录,执行以下命令即可完成安装:

1
$ python setup.py install

但我在 RHEL7 操作系统按照上述方法编译安装时,并没有成功,错误原因是“找不到文件 yaml.h”。我的解决方案是:首先安装 libYAML,再安装 PyYAML。

安装 libYAML

libYAML 是使用 C 语言实现的 YAML 解析库,截至目前的最新版本为 0.1.7。可以很容易地将其源代码包下载至本地。

使用下面的命令将安装包解压:

1
$ tar -zxvf yaml-0.1.7.tar.gz

解压后,使用 cd 进入解压得到的文件夹,执行安装命令(很可能需要 root 权限):

1
2
3
$ ./configure
$ make
$ make install

安装 PyYAML

libYAML 安装完成之后,就可以继续安装 PyYAML 了。在 PyYAML 解压得到的文件夹中执行:

1
$ python setup.py install

运行上述命令将为系统默认的 Python 安装 PyYAML。但如果你计算机上同时安装了 Python2 与 Python3,那么需要使用两个版本的 Python 各自执行一遍安装程序:

1
2
$ python2 setup.py install
$ python3 setup.py install

演示程序

PyYAML 模块的使用非常简单,使用 yaml.load() 方法解析 YAML 文档,使用 yaml.dump() 方法将数据格式化为 YAML。其中 yaml.load() 方法既可以解析字符串,也可以处理打开的 YAML 文件。以下是采用 Python 3 语法的一个简单示例:

1
2
3
4
5
>>> import yaml
>>> yaml.load('greeting: "Hello world!"')
{'greeting': 'Hello world!'}
>>> yaml.load(StringIO('foo: [bar, baz]'))
{'foo': ['bar', 'baz']}

同样,yaml.dump() 函数也可以处理两种场景。如果你希望该函数返回符合 YAML 格式的字符串,你可以只输入要编码的数据;如果你希望将数据编码输入到文件,只需多传入一个可写的文件流对象:

1
2
3
4
5
6
7
8
>>> import yaml
>>> data = {'foo':{'bar': 'hello', 'baz': 'world'}}
>>> print(yaml.dump(data))
foo: {bar: hello, baz: world}
>>> pseudo_file = StringIO()
>>> yaml.dump({'greeting': 'Hello world!'}, pseudo_file)
>>> print(pseudo_file.getvalue())
{greeting: Hello world!}

你或许已经发现了:yaml.dump() 函数的输出比较紧凑,与 YAML 以缩进来表示层次的语法不甚一致。为增强人类可读性,你可以为该函数增加一个 default_flow_style=False 参数来强制使用缩进形式的编码风格:

1
2
3
4
5
>>> data = {'foo':{'bar': 'hello', 'baz': 'world'}}
>>> print(yaml.dump(data, default_flow_style=False))
foo:
bar: hello
baz: world