10 KiB
Python YAML:如何加载、读取和编写 YAML
YAML 是“YAML 不是标记语言”的递归首字母缩写,是一种人类可读的数据序列化语言。它通常用于配置文件,但也可用于数据交换。最常用的 python YAML 解析器是 PyYAML,这是一个允许你加载、解析和编写 YAML 的库,很像 Python 的 JSON 库帮助你使用 JSON。
这篇文章教你如何用 PyYAML 加载、读取和写入 YAML 文件。此外,您还将了解如何在您的系统上安装它,以及 YAML 与 JSON 等替代产品的比较。
目录
- 什么是 YAML?
- 为什么将 YAML 与 Python 结合使用?
- 安装和导入 PyYAML
- 用 Python 读取并解析 YAML 文件
- 用 Python 解析 YAML 字符串
- 解析包含多个 YAML 文档的文件
- 将 YAML 写入(或转储)到文件中
- 使用 Python 将 YAML 转换成 JSON】
- 将 JSON 转换成 YAML
- PyYAML safe _ load()vs load()
- 追加资源
什么是 YAML?
YAML 标志
据官网(1)YAML 是一种对所有编程语言都友好的数据序列化语言。 YAML 最常用于配置文件,但也用于数据交换。
YAML 对于人类来说很容易写和读,即使对于非程序员来说也是如此。同时,解析 YAML 也很容易,尤其是使用 Python 和 PyYAML 库!它的人性化和可读性是 YAML 相对于其他格式的最大优势,比如 JSON 和 XML。
这些是 YAML 最突出的特征:
- 您可以在 YAML 文件中使用注释
- 您可以使用
---分隔符在一个 YAML 文件中存储多个文档。Kubernetes 定义中经常使用的一个特性。 - 对人类来说很容易阅读
- 很容易为计算机解析
1)有趣的事实是,YAML 官方网站是以有效的 YAML 文件的形式编写的。
为什么将 YAML 与 Python 结合使用?
如果你问我,YAML 是完美的配置文件。这正是我和许多其他开发人员使用它最多的方式。其他人似乎同意,因为许多大型项目,如 Docker 和 Kubernetes,使用 YAML 来定义部署。它的语法比常用的替代方法更丰富。ini 文件,但是看起来还是不错的,并且易于编写和解析。
不过,将 YAML 与 Python 结合使用也有一些缺点:
- YAML 不是标准 Python 库的一部分,而 XML 和 JSON 是
- 它对缩进的依赖有时令人沮丧(不过,Python 开发人员已经习惯了,对吧?)
- 对于简单的用例,比如简单对象的数据交换,它可能有点太通用了。
如果您正在寻找一种良好的数据交换和存储格式,我推荐 JSON、XML 或其他更有效的格式,如协议缓冲区和 Avro。
安装和导入 PyYAML
有多个 Python 包可以解析 YAML 数据。然而,PyYAML 是解析 YAML 最流行也是最完整的实现。PyYAML 不是标准 Python 库的一部分,这意味着您需要用 Pip 来安装它。使用以下命令安装 PyYAML,最好是在虚拟环境中:
$ pip install pyyaml
在某些系统上,您需要使用 pip3:
$ pip3 install pyyaml
要在您的脚本中使用 PyYAML,导入模块,如下所示。请注意,您没有导入“pyyaml”,而只是导入了“yaml”:
import yaml
用 Python 读取并解析 YAML 文件
一旦导入了 YAML 解析器,我们就可以加载一个 YAML 文件并解析它。YAML 文件通常带有扩展名.yaml或.yml。让我们以下面的 YAML 文件为例,名为config.yaml:
rest:
url: "https://example.org/primenumbers/v1"
port: 8443
prime_numbers: [2, 3, 5, 7, 11, 13, 17, 19]
加载、解析和使用这个配置文件非常类似于用 Python JSON 库加载 JSON。首先,我们打开文件。接下来,我们用yaml.safe_load()函数解析它。请注意,我对输出做了一点修改,以便于您阅读:
>>> import yaml
>>> with open('config.yml', 'r') as file
... prime_service = yaml.safe_load(file)
>>> prime_service
{'rest':
{ 'url': 'https://example.org/primenumbers/v1',
'port': 8443
},
'prime_numbers': [2, 3, 5, 7, 11, 13, 17, 19]}
>>> prime_service['rest']['url']
https://example.org/primenumbers/v1
YAML 解析器返回最符合数据的常规 Python 对象。在这种情况下,它是一个 Python 字典。这意味着可以使用所有常规的字典特性,比如使用带有默认值的get()。
这是同一个例子,但是是交互式的,所以你可以自己尝试一下:
https://crumb . sh/embed/xbk 87 vueyxv
用 Python 解析 YAML 字符串
您可以使用yaml.safe_load()来解析各种有效的 YAML 字符串。这里有一个例子,它将一个简单的条目列表解析成一个 Python 列表:
>>> import yaml
>>>
>>> names_yaml = """
... - 'eric'
... - 'justin'
... - 'mary-kate'
... """
>>>
>>> names = yaml.safe_load(names_yaml)
>>> names
['eric', 'justin', 'mary-kate']
解析包含多个 YAML 文档的文件
YAML 允许你在一个文件中定义多个文档,用三个破折号(---)分隔它们。PyYAML 也会很乐意解析这样的文件,并返回一个文档列表。您可以通过使用yaml.safe_load_all() 功能来实现。该函数返回一个生成器,该生成器将依次返回所有文档。
注意,只要从 YAML 读取文档,就需要打开文件,所以必须在with子句内进行处理。下面是一个演示此功能的交互式示例:
https://crumb.sh/embed/3FkJXZuuK4H
将 YAML 写入(或转储)到文件中
虽然大多数人只会把 YAML 作为配置文件来读,但是写 YAML 也很方便。示例用例可能是:
- 使用用户的当前设置创建初始配置文件
- 将程序状态保存在一个易于阅读的文件中(而不是使用 Pickle 之类的东西)
在以下示例中,我们将:
- 像我们之前做的那样创建一个带有姓名的列表
- 用
yaml.dump将名称保存到 YAML 格式的文件中 - 阅读并打印文件,作为一切按预期工作的证明
给你:
https://crumb . sh/embed/maabpr 3 qx
下面是与非交互式示例相同的代码:
import yaml
names_yaml = """
- 'eric'
- 'justin'
- 'mary-kate'
"""
names = yaml.safe_load(names_yaml)
with open('names.yaml', 'w') as file:
yaml.dump(names, file)
print(open('names.yaml').read())
- eric
- justin
- mary-kate
使用 Python 将 YAML 转换成 JSON】
如果您需要将 YAML 转换成 JSON,您可以像上面那样简单地解析 YAML。在下一步中,您可以使用 JSON 模块将对象转换成 JSON。
在本例中,我们打开一个基于 YAML 的配置文件,用 PyYAML 解析它,然后用 JSON 模块将其写入一个 JSON 文件:
https://crumb.sh/embed/rAUgstafYtA
下面是与非交互式示例相同的代码:
import yaml
import json
with open('config.yml', 'r') as file:
configuration = yaml.safe_load(file)
with open('config.json', 'w') as json_file:
json.dump(configuration, json_file)
将 JSON 转换成 YAML
为了完整起见,让我们反过来做:将 JSON 转换成 YAML:
https://crumb.sh/embed/CjAnBJVynyU
如何用 Python 将 JSON 转换成 YAML
PyYAML safe _ load()vs load()
你会遇到很多 PyYAML 用法的例子,其中使用了load()而不是safe_load()。我故意到现在才告诉你load()功能。由于大多数人都有工作要做,并且倾向于快速复制粘贴一些示例代码,我希望他们使用最安全的方法用 Python 解析 YAML。
然而,如果你对这两者之间的区别感到好奇,这里有一个简短的总结:load()是一个非常强大的函数,就像泡菜,如果你知道那个函数的话。这两种方法都非常不安全,因为它们允许攻击者执行任意代码。PyYAML 的 load 函数允许您序列化和反序列化完整的 Python 对象,甚至执行 Python 代码,包括调用os.system库,该库可以在您的系统上执行任何命令。
在最近的 PyYAML 版本中,load()函数被弃用,当您以不安全的方式使用它时,它会发出一个很大的警告。
如果你像我们 99%的人一样解析常规的 YAML 文件,你应该总是使用safe_load(),因为它只包含了 load 函数的一个子集。所有可怕的、任意代码执行类型的东西都被剔除了。
追加资源
以下是您可能想继续使用的一些资源:
- 【PyYAML 官方文档
- 如何用 Python 打开、读取和写入文件
- 在 Python 中使用 JSON
- 命令行上的 JSON
