使用PyYAML处理Python YAML

335 阅读5分钟

YAML 是YAML Aint' Markup Language 的缩写。它被广泛用于为许多不同的DevOps工具和应用程序编写和存储配置文件。它被写成一个文本文件,可以很容易地被人类阅读,而且简单易懂。它使用**.yaml.yml** 作为扩展名。它类似于其他数据序列化语言,如JSON,和XML。

数据序列化是在网络上进行配置文件传输和恢复的标准格式。

使用YAML在Python中编写的数据序列化文件可以很容易地在网络上发送,然后可以使用另一种编程语言对其进行去序列化,以便使用。它支持多种语言,如Python、JavaScript、Java和其他许多语言。 这些语言都有YAML库,使它们能够解析和使用YAML文件。在这篇文章中,我们将用Python来回顾YAML的一些例子。它还支持数据结构,如列表、字典和数组。

YAML vs XML vs JSON

让我们看一个配置文件的例子,看看这三个版本的概况和语法。

YAML - YAML不是一种标记语言
configuration:
  name: my-api-config
  version: 1.0.0
  about: "some description"
  description: |
    Lorem ipsum dolor sit amet, 
    consectetur adipiscing elit
  scripts:
    "start:dev": main.py
  keywords: ["hello", "there"]

XML - 可扩展标记语言
<configuration>
  <name>my-api-config</name>
  <version>1.0.0</version>
  <about>some description</about>
  <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit</description>
  <scripts>
    <start:dev>main.py</start:dev>
  </scripts>
  <keywords>hello</keywords>
  <keywords>there</keywords>
</configuration>

JSON - JavaScript对象符号法
{
    "configuration": {
        "name": "my-api-config",
        "version": "1.0.0",
        "about": "some description",
        "description": "Lorem ipsum dolor sit amet, \nconsectetur adipiscing elit\n",
        "scripts": {
            "start:dev": "main.py"
        },
        "keywords": [
            "hello",
            "there"
        ]
    }
}

分解YAML文件

我们例子中的YAML文件显示了一个应用程序的一些配置设置。与其他两种配置文件格式相比,有一些明显的区别,它们甚至使用了更多的符号解析。YAML 的核心是使用键:值对来存储文件中的数据。键应该是字符串,它们也可以用或不用引号来写。值可以包括多种数据类型,如整数、字符串、列表、布尔运算等等。

在编写YAML文件时,需要适当的缩进。不允许使用制表符空格,所以我们需要小心,否则我们的文件就会出现提示错误。所以,这真的很简单,而且是人类可读的。与XML或JSON文件不同,我们在阅读它时不必解析多个符号:

configuration:
  name: my-api-config
  version: 1.0.0
  about: "some description"
  # This is a comment
  description: |
    Lorem ipsum dolor sit amet, 
    consectetur adipiscing elit
  scripts:
    "start:dev": main.py
  keywords: ["hello", "there"]

我们还可以像上面写的那样在我们的文件中加入注释,以及使用**| 管道字符**的多行字符串,如示例代码中所示。

用PyYaml处理YAML文件

在这一节中,我们将使用PyYaml模块对YAML文件进行一些基本操作,如读、写和修改数据。

  • 安装PyYaml
pip install pyyaml

读取一个yaml文件

假设我们有一个带有一些配置的YAML文件,我们想用Python来读取其内容。

文件名config_one.yml

configuration:
  name: my-api-config
  version: 1.0.0
  about: some description
  stack:
    - python
    - django

接下来,我们将创建一个新的Python文件并尝试读取yml文件。

文件名PyYaml.py

import yaml
with open("config_one.yml", "r") as first_file:
    data = yaml.safe_load(first_file)
    print(type(data))
    print(data)
"""
Output:

<class 'dict'>
{'configuration': {'name': 'my-api-config', 'version': '1.0.0', 'about': 'some description', 'stack': ['python', 'django']}}

"""

解释一下

我们在导入 **pyyaml**模块,使用 import yaml.要读取一个yaml文件,我们首先要以读取模式打开该文件,然后用 safe_load().因为有不同的构造函数,如load() 函数,所以有多个加载器。*使用load()是不安全的,因为它允许执行几乎所有的脚本,包括恶意代码,这一点都不安全。*因此,safe_load() 是推荐的方式,它不会创建任何任意的对象。

我们正在使用Python代码打印出我们yaml文件中的数据类型。控制台显示的输出为**<class dict>**而包含的数据被格式化为一个字典,以 **key: value**对。

修改我们的yaml文件

要修改我们已经加载的文件,我们必须首先确定数据类型。如果键的值是一个字符串,我们必须把所有的附加值放在一个列表中,然后才能更新这个**key: value**对:

import yaml

with open("config_one.yml", "r") as first_file:
    data = yaml.safe_load(first_file)
    print(type(data))
    # Accessing our <class dict> and modifying value data using a key
    data["configuration"]["stack"] = ["flask", "sql"]
    # Appending data to the list
    data["configuration"]["stack"].append("pillow")
    print(data)


"""
Output:

<class 'dict'>
{'configuration': {'name': 'my-api-config', 'version': '1.0.0', 'about': 'some description', 'stack': ['flask', 'sql', 'pillow']}}

"""

解释

我们在这里有一个嵌套的字典,我们正在使用我们试图修改其值的键来访问数据。还有一个 **append()**函数,它将另一个项目添加到值的列表中。*注意,这些修改只在运行时进行。*我们将把这些值写入我们的新的yaml文件中。

用修改后的数据写一个yaml 文件

只需几行代码,就可以将上述数据连同修改后的值写入一个新的文件中:

import yaml

with open("config_one.yml", "r") as first_file:
    data = yaml.safe_load(first_file)
    print(type(data))

    # Accessing our <class dict> and modifying value data using a key
    data["configuration"]["stack"] = ["flask", "sql"]

    # Appending data to the list
    data["configuration"]["stack"].append("pillow")
    print(data)

# Writing a new yaml file with the modifications
with open("new_config.yaml", "w") as new_file:
    yaml.dump(data, new_file)

文件名new_config.yaml

configuration:
  about: some description
  name: my-api-config
  stack:
  - flask
  - sql
  - pillow
  version: 1.0.0

解释

我们将不得不用下面的语法提供新的文件名,然后用 **yaml.dump**带2个参数,数据变量包含原始的yaml代码以及对其进行的修改,第二个参数为 **new_file**变量,用于执行写入方法。我们可以看到,新文件保留了原文件的代码,以及我们对它所做的修改。

总结

在这篇文章中,我们了解了yaml文件的基本结构,并使用它来读取、修改和写入配置到一个新文件。我们还将其与JSON和XML进行了比较,对同一个YAML文件使用不同的语法。用来编写YAML文件的极简方法显然是非常简单的,而且是人类可读的,这使得它成为各种技术栈所使用的最流行的文本格式配置文件之一。