您的位置:

Python YAML 解析器

在本教程中,我们将学习如何使用 Python 对 YAML 文件进行读取、写入或执行各种操作。我们将讨论 YAML 文件格式,它的用法,以及我们如何使用 Python 操作它。

让我们简单介绍一下 YAML。

什么是 YAML?

YAML 是另一种标记语言的缩写。它以序列化的方式存储配置文件数据;由于它是一种人类可读的数据格式,并且经常用于数据存储或传输,因此近年来它变得非常流行。

YAML 支持三种数据类型——标量(字符串、整数和浮点)、列表和关联数组。

YAML 文件与一起保存。yaml 或。yml 扩展。我们可以使用 YAML 的注释,使用#符号。内部每个子项前面都有一个连字符。可以使用缩进来嵌套这些值。

YAML 的优势

YAML 的一些重要优势如下。

  • 所有编程语言都支持 YAML - 我们需要用一种语言写 YAML,几乎可以和所有编程语言一起使用,无需任何修改。
  • 对象序列化- 我们可以序列化 YAML 数据格式。
  • 易读- 没有硬写的规则来创建 YAML 文件。简单的缩进用于定义单个块和文档。

在进一步开始之前,我们假设您对 Python 有基本的了解,或者对 Python 编程语言有初级编程经验。

PyYAML 模块

PyYAML 是一个 Python 模块,它提供了一系列方法来对 YAML 文件执行一些操作。我们可以很容易地将 YAML 文件转换成字典并阅读其内容。在 YAML 模块的帮助下,我们可以读写复杂的配置 YAML 文件,序列化和持久化 YAML 数据。

要使用 PyYAML,我们需要在系统中安装它。下面是 PyYAML 模块的安装步骤。

安装 PyYAML

我们可以用下面的方法安装它。

  • 使用 pip 命令安装
  • 通过源代码安装

使用画中画命令

我们可以使用 pip 命令安装它。在终端中键入以下命令来安装 PyYAML 模块。


pip install pyyaml

通过源代码安装

如果使用 pip 命令遇到错误,我们可以使用另一种安装方式。遵循以下说明。

  • 打开 PyYAML Github 资源库,点击代码段,下载 ZIP 文件。
  • 提取下载的压缩文件。
  • 现在打开终端,更改解压 zip 文件的目录。
  • 现在运行一个 python setup.py 命令,然后点击 enter 按钮。它会在你的机器上安装 PyYAML 模块。

阅读 YAML 文件

首先,我们创建一个名为 sample.yaml 的新 YAML 文件,该文件将用于使用 PyYAML 模块进行读取。

样品 py


# YAML Document starts with ---
# Comments start with #
UserName: Antonio
Password: fire123 * 
phone: 9879098
Skills:
      -Python
      -SQL
      -Django
      -Rest Framework
      -JavaScript 

使用 yaml.load() 方法读取 yaml 文件。这个方法解析 YAML 对象并将其转换成 Python 字典,这样我们就可以轻松地阅读内容。这个过程被称为将 YAML 文件反序列化为 Python。

load()方法接受一个参数,该参数可以是字节字符串、打开的二进制文件对象、Unicode 字符串或打开的 YAML 文件对象。

如果我们将文件或字节字符串作为参数传递,它应该用 utf-8、utf-16-be 或 utf-16-le 编码。

让我们理解下面的例子。

示例-


import yaml

from yaml.loader import SafeLoader
#open yaml file in read mode
with open('sample.yaml', 'r') as f:
    data = list(yaml.load(f, Loader=SafeLoader))
    print(data)

输出:

[{'UserName': 'Antonio', 'Password': 'fire123 *', 'phone': 9879098, 'Skills': '-Python -SQL -Django -Rest Framework -JavaScript'}]

解释-

我们已经将上面代码中的 yaml 文件导入了 YAML 及其加载器。 load() 功能附带了四种类型的 Loader。

  • 安全加载器- 我们在上面的例子中使用了这个加载器。它安全地装载了 YAML 的一部分。当输入来自不受信任的来源时,通常使用它。
  • baseliloader-它将所有基本的 YAML 标量加载为字符串。
  • FullLoader - 它的工作原理与 BaseLoader 相同,但避免了任意代码执行。如果输入来自不受信任的来源,则可能构成安全威胁。
  • unseloader-不可信源输入推荐 Loader,一般用于向后兼容。

load() 方法返回我们键入列表中的生成器对象,可以访问任何元素。

我们也可以通过字典的形式得到相同的值。让我们理解下面的例子。

我们也可以通过字典的形式得到 yaml 值。让我们理解下面的例子。

示例- 2


import yaml

from yaml.loader import FullLoader
#open yaml file in read
with open('sample.yaml', 'r') as f:
    yaml_data = yaml.load(f, Loader=FullLoader)
    print(yaml_data)

输出:

{'UserName': 'Antonio', 'Password': 'fire123 *', 'phone': 9879098, 'Skills': '-Python -SQL -Django -Rest Framework -JavaScript'}

我们将标量参数安全加载器更改为完全加载器,将 YAML 数据转换为字典。这个加载器的优点是,我们不需要将加载的数据类型转换成列表。

阅读多份 YAML 文件

我们可以使用 yaml.load_all() 方法读取多个 yaml 文档。一个 YAML 文件可以有多个文档。下面是单个文件中多个文档的示例。

样品。yaml


---
UserName: Antonio
Password: fire123 * 
phone: 9879098
Skills:
      -Python
      -SQL
      -Django
      -Rest Framework
      -JavaScript 
...

---
  UserName: Maino
  Password: fire123 * 
  phone: 9879098
  Skills:
      -Python
      -SQL
      -Django
      -Rest Framework
      -JavaScript 
...

---
  UserName: George
  Password: fire123 * 
  phone: 9879098
  Skills:
      -Python
      -SQL
      -Django
      -Rest Framework
      -JavaScript 
...

文档以三个破折号(-)开始,以三个点(…)结束。让我们理解下面的例子。

示例-


import yaml

from yaml.loader import SafeLoader
#open yaml file in read
with open('sample.yaml', 'r') as f:
    yaml_data = list(yaml.load_all(f, Loader=SafeLoader))
    print(yaml_data)

输出:

[{'UserName': 'Antonio', 'Password': 'fire123 *', 'phone': 9879098, 'Skills': '-Python -SQL -Django -Rest Framework -JavaScript'}, {'UserName': 'Maino', 'Password': 'fire123 *', 'phone': 9879098, 'Skills': '-Python -SQL -Django -Rest Framework -JavaScript'}, {'UserName': 'George', 'Password': 'fire123 *', 'phone': 9879098, 'Skills': '-Python -SQL -Django -Rest Framework -JavaScript'}]

解释-

load() 方法返回我们键入列表中的生成器对象,这样我们就可以访问任何元素。在前面的例子中,我们学习了如何读取 YAML 文件。现在,我们将了解如何将数据转储到 YAML 文件中。

用 PyYAML 模块写 YAML 文件

将 Python 数据写入 YAML 被称为序列化。要将数据转储到 yaml 文件中,我们将使用 yaml.dump() 方法。让我们理解下面的例子。

示例-


import yaml

# dict object
members = [{'User': 'Zoey', 'Password': 'Xavier@123', 'Phone': 345464, 'Skills': ['Python', 'SQL', 'Django', 'Rest Framework', 'JavaScript']},
           {'name': 'Zaara', 'occupation': 'Dentist'}]

# Convert Python dictionary into a YAML document
print(yaml.dump(members))

输出:

Password: [email protected]
  Phone: 345464
  Skills:
  - Python
  - SQL
  - Django
  - Rest Framework
  - JavaScript
  User: Zoey
- name: Zaara
  occupation: Dentist

解释-

dump() 方法将 Python 对象转换为 YAML 格式,并将它们写入 YAML 文件。我们在上面的例子中做了同样的事情。 dump() 方法接受两个参数——数据和流。

数据参数表示将转换成 YAML 流的 Python 对象。第二个参数是一个必须是文本或二进制文件的文件。YAML 流数据被写入给定的文件名;否则, dump() 将返回生成的文档。

让我们理解在文件中写入 Python 数据的例子。

示例- 2:


import yaml

# dict object
python_data = [{'User': 'Zoey', 'Password': 'Xavier@123', 'Phone': 345464, 'Skills': ['Python', 'SQL', 'Django', 'Rest Framework', 'JavaScript']},
           {'name': 'Zaara', 'occupation': 'Dentist'}]

with open('NewDetails.yaml', 'w') as f:
    data = yaml.dump(python_data, f, sort_keys=False, default_flow_style=False)

输出:

新细节。yaml

- User: Zoey
  Password: [email protected]
  Phone: 345464
  Skills:
  - Python
  - SQL
  - Django
  - Rest Framework
  - JavaScript
- name: Zaara
  occupation: Dentist

解释

在上面的例子中,首先,我们定义了要写入文件的 Python 字典。然后,我们打开了新的细节。YAML 文件处于写入模式。我们使用了 dump()方法,并将 Python dict 对象和另外两个标签一起传递。这些标签是-

  • default_flow_style -用于以适当的缩进显示嵌套块的内容。默认为真。如果我们将其值设置为 false,并且嵌套列表中的值以流动样式显示,它将以适当的缩进显示块样式的内容。
  • sort_keys -用于按字母顺序排序按键。默认为真。如果我们将其值设置为 false,它将保持插入顺序。

转储多个 YAML 文档

yaml.dump_all() 方法用于将多个 yaml 文档转储到一个流中。该方法将产生 Python 对象的列表或生成器序列化为 YAML 文档,并将第二个可选参数作为打开的文件。

让我们理解下面的例子。

示例-


import yaml

# dict object
python_data = [{'User': 'Zoey', 'Password': 'Xavier@123', 'Phone': 345464, 'Skills': ['Python', 'SQL', 'Django', 'Rest Framework', 'JavaScript']},
           {'name': 'Zaara', 'occupation': 'Software Engineer'}]

data1 = yaml.dump(python_data)
print("Using dump() method")
print(data1)

data2 = yaml.dump_all(python_data)
print("Using dump_all() method")
print(data2)

输出:

Using dump() method
- Password: [email protected]
  Phone: 345464
  Skills:
  - Python
  - SQL
  - Django
  - Rest Framework
  - JavaScript
  User: Zoey
- name: Zaara
  occupation: Dentist

Using dump_all() method
Password: [email protected]
Phone: 345464
Skills:
- Python
- SQL
- Django
- Rest Framework
- JavaScript
User: Zoey
---
name: Zaara
occupation: Dentist

Python YAML 排序键

sort_keys 是将 Python 数据转储到文件中时使用的可选标记。如果我们将其设置为真,它将按字母顺序对 YAML 文档的所有键进行排序。让我们理解下面的例子。

示例-


import yaml

from yaml.loader import FullLoader
#open yaml file in read
with open('sample.yaml', 'r') as f:

    print("Before Sorting?..")
    yaml_data = yaml.load(f, Loader=FullLoader)
    print(yaml_data)

    print("After Sorting......")
    sorted_data = yaml.dump(yaml_data, sort_keys=True)
    print(sorted_data)

输出:

import yaml

from yaml.loader import FullLoader
#open yaml file in read
with open('sample.yaml', 'r') as f:

    print("Before Sorting?..")
    yaml_data = yaml.load(f, Loader=FullLoader)
    print(yaml_data)

    print("After Sorting......")
    sorted_data = yaml.dump(yaml_data, sort_keys=True)
    print(sorted_data)

YAML 文件格式

PyYaml 模块提供了在 Yaml 文件中写入 YAML 文档时格式化该文件的功能。dump()方法支持各种格式参数。以下是格式参数。

参数-

  • 缩进- 有助于设置首选缩进。
  • 宽度- 有助于设置首选宽度。
  • canonical=True - 它强制标量和集合的首选样式。

让我们理解下面的例子-

示例-


import yaml

from yaml.loader import FullLoader
#open yaml file in read
with open('sample.yaml', 'r') as f:

    yaml_data = yaml.load(f, Loader=FullLoader)
    sorted_data = yaml.dump(yaml_data, indent=10, default_flow_style=False)
    print(sorted_data)

输出:

Password: fire123 *
Skills: -Python -SQL -Django -Rest Framework -JavaScript
UserName: Antonio
phone: 9879098

自定义 Python 类 YAML 可序列化

我们可以创建自定义 Python 类,它可以将 YAML 转换为自定义 Python 对象,而不是列表或内置类型。

让我们理解下面的例子-

示例-


import yaml
from yaml.loader import UnsafeLoader

class Person:
    def __init__(self, user, password):
        self.user = user
        self.password = password

    def __repr__(self):
        return "%s(user=%r, password=%r)" % (
            self.__class__.__name__, self.user, self.password)

# Make Python Class YAML Serializable
person = Person('Jessa', 'queue@123')
yaml_obj = yaml.dump(person)

# Deserialize YAML into a Custom Python Class
new_person = yaml.load(yaml_obj, Loader=UnsafeLoader)
print(new_person.user, new_person.password)

输出:

Jessa [email protected]

带 PyYAML 的自定义标签

我们可以根据应用需求创建自定义标签,并在解析 YAML 文件时为自定义标签分配默认值。为此,它涉及下面给出的某些步骤。

  • 在第一步中,我们定义一个构造器,该函数接受 loader 和 YAML 节点。
  • 我们在创建的构造器中调用construct _ mapping()方法,该方法将返回一个对应于 YAML 节点的 Python 字典。它将返回一个带有字典的构造器。
  • 返回的构造器将被传递给 add_constructor() ,后者将 YAML 表示图转换为本机 Python 对象。一个构造器接受一个 Loader 实例,一个节点返回 Python 对象。
  • 现在,load()方法可以根据需要接受许多具有 add_constructor()中定义的相同自定义标记的字段。没有值的字段将被分配在 init()方法中定义的默认值。

让我们理解下面的例子。

示例-


import yaml

def custom_constructor(loader, node) :
    fields = loader.construct_mapping(node)
    return Test(**fields)

yaml.add_constructor('!Custom Tags', custom_constructor)

class Test(object) :

    def __init__(self, user, password, phone=11000) :
        self.user = user
        self.password = password
        self.phone = phone

    def __repr__(self):
        return "%s(user=%s, password=%r,phone=%r)" % (self.__class__.__name__, self.user, self.password, self.phone)

print (yaml.load("""
- !Custom Tags { user: 'Sam' }
- !Custom Tags { user: 'Gaby', password: 'admin@123',phone: 5656}"""))

输出:

[Custom Tags(user=Sam, [email protected],phone=1100), Test(name=Gaby, password= [email protected], phone=5656)]

PyYAML 模块中的转换表

下面是 PyYAML 模块用来将 Python 对象转换成 YAML 等价对象的表格。 dump() 方法在编码时使用翻译。

| YAML 日 | Python 类型 | | !!空 | 没有人 | | !!弯曲件 | 弯曲件 | | !!漂浮物 | 浮动 | | !!(同 Internationalorganizations)国际组织 | (同 Internationalorganizations)国际组织 | | !!二进制的 | 字符串(Python3 中的字节) | | !!时间戳 | 日期时间.日期时间 | | !!奥马普!!成对 | 配对列表 | | !!设置 | 一组 | | !!顺序 | 目录 | | !!潜艇用热中子反应堆(submarine thermal reactor 的缩写) | 字符串或 unicode(Python 中字符串) | | !!地图 | 字典 |

YAML 错误

YAML 解析器在出现任何错误时都会引发一个名为的异常错误。借助这个错误,我们可以调试这个问题。因此,建议在 try-expect 块中使用 YAML 序列化代码。让我们理解下面的例子。

示例-


import yaml

try:
    config = yaml.load('Userdetails.yaml')
except yaml.YAMLError:
    print("Error in configuration file:")

代币

令牌通常用于低级应用,如语法突出显示。我们可以产生 scan() 方法来产生一组代币。让我们理解下面的例子。

示例-


import yaml

with open('sample.yaml') as f:
    data = yaml.scan(f, Loader=yaml.FullLoader)

    for token in data:
        print(token)

输出:

StreamStartToken(encoding=None)
DocumentStartToken()
BlockMappingStartToken()
KeyToken()
ScalarToken(plain=True, style=None, value='UserName')
ValueToken()
ScalarToken(plain=True, style=None, value='Antonio')
KeyToken()
ScalarToken(plain=True, style=None, value='Password')
ValueToken()
ScalarToken(plain=True, style=None, value='fire123 *')
KeyToken()
ScalarToken(plain=True, style=None, value='phone')
ValueToken()
ScalarToken(plain=True, style=None, value='9879098')
KeyToken()
ScalarToken(plain=True, style=None, value='Skills')
ValueToken()
ScalarToken(plain=True, style=None, value='-Python -SQL -Django -Rest Framework -JavaScript')
BlockEndToken()
DocumentEndToken()
StreamEndToken()

Python YAML 到 XML

可以使用 XMLPlain 模块将 YAML 数据转换为 XML 格式。XML 是可扩展标记语言的缩写名称,它使用 HTML 标签来定义标签。

obj_from_yaml() 方法用于从 yaml 流或字符串生成 XML 普通对象。为了保持 XML 普通对象元素的有序,YAML 流被存储为 OrderDict。

让我们获取包含员工详细信息的 YAML 文件示例,并将其转换为 XML 文件。

示例-


StudentRecord:
-Student:
    'rollno': st01
    name: Alexa
    class: 10
    subject: python, Java
-Student:
    'rollno': st02
    name: Prince
    class: 11
    subject: Webservices, REST API

让我们理解代码实现。

示例-


import xmlplain

# Read the YAML file
with open("student.yaml") as inf:
    root = xmlplain.obj_from_yaml(inf)

# Output back XML
with open("student.xml", "w") as outf:
    xmlplain.xml_from_obj(root, outf, pretty=True)

结论

在本教程中,我们学习了 YAML 和 PyYAML 模块的一些重要概念。我们介绍了如何创建自定义标签,将 YAML 文件的内容作为字典加载到 Python 程序中。我们还讨论了如何操作 YAML 格式的文件。本教程包含了该库相当简短的基本功能。