如何使用 Python 3.11 的新 TOML 解析器 tomllib

TOML 解析器将包含在 Python 3.11 中

Python 语言指导委员会已经接受了 PEP 680,它向 Python 标准库添加了一个 TOML 解析器。 这意味着在 Python 3.11 中,您将能够 import tomllib 并有一个可以解析 TOML 文件的模块。

但是什么是 TOML 文件以及为什么要将 TOML 解析器添加到 Python? 此博客解释了 TOML 文件的外观、它们的使用方式以及可让您解析它们的 Python 代码。

TOML 代表汤姆的显而易见的最小语言。 它是一种在文本文件中构造数据的方法,很像 JSON、XML 和 YAML 文件所做的。 TOML 标准的建立是为了让人们很容易在文本编辑器中编写 TOML 文件用作配置文件。 这是一个示例 TOML 文件:

# My Dungeons & Dragons character.
name = "Mordnilap"
class = "Magic user"
maxHP = 14
currentHP = 2

inventory = ["apple", "enchanted staff", "healing potion"]

cursed = false

[spells]
# The integers represent how many times a day they can be cast.
fireball = 3
featherFall = 2

使用 Python 3.11 中的 TOML 解析器,您将能够解析此文本并转换为以下 Python 字典:

{'class': 'Magic user',
 'currentHP': 2,
 'cursed': False,
 'inventory': ['apple', 'enchanted staff', 'healing potion'],
 'maxHP': 14,
 'name': 'Mordnilap',
 'spells': {'featherFall': 2, 'fireball': 3}}

Python 已经有了用于解析 XML 和 JSON 文本的标准库模块(使用 xmljson modules, respectively.) 有用于解析 TOML 文件的第三方模块,但 Python 3.11 将在标准库中包含一个,以便所有 Python 程序都可以访问它,而无需安装第三方 TOML 解析模块的额外步骤。

TOML 文件并非特定于 Python。 TOML 只是文本文件的一种格式,用任何编程语言编写的程序都可以读取它们。 但是 Python 生态系统中的许多工具都使用 TOML 格式,因此将 TOML 解析器添加到 Python 标准库中也就不足为奇了。

正如您在上面的示例 TOML 文件中看到的,TOML 是一种用于为配置文件构建数据的出色格式。 它没有 Excel 电子表格或 CSV 文件使用的相同列和行格式。

正如您在上面的示例 TOML 文件中看到的,TOML 是一种用于为配置文件构建数据的出色格式。 它没有 Excel 电子表格或 CSV 文件使用的相同列和行格式。

在 Python 3.11 中,TOML 模块将被命名为 tomllib,因为第三方模块名为 toml 已经存在。 3.11中的TOML模块将基于现有的 tomli 第三方模块。

使用 tomli 编写 Python 代码

您不必等到 Python 3.11 发布后立即使用它。 你可以安装 tomli 通过运行 pip 工具 pip3 install --user tomli 在 macOS 和 Linux 的终端窗口中,或通过运行 pip install --user tomli 在 Windows 的命令提示符窗口中。 (不要从 Python 交互式 shell 运行它;那不起作用。)

很像 json 模块具有名为 load()loads() (发音为“load s”或“load string”,而不是“loads”), tomli 第三方库(和未来 tomllib Python 3.11 中的模块)有 load()loads() 功能。

例如,假设我们在名为 dnd_character.toml 的 TOML 文件中有上面的龙与地下城文本。 我们可以使用以下代码读入我们的 Python 程序:

import tomli  # import tomllib in Python 3.11
import pprint

with open('dnd_character.toml') as fileObj:
  content = fileObj.read()
  dnd_char = tomli.loads(content)
pprint.pprint(dnd_char)

该程序的输出来自 pprint “漂亮打印”模块如下:

{'class': 'Magic user',
 'currentHP': 2,
 'cursed': False,
 'inventory': ['apple', 'enchanted staff', 'healing potion'],
 'maxHP': 14,
 'name': 'Mordnilap',
 'spells': {'featherFall': 2, 'fireball': 3}}

toml.loads() 函数采用我们从名为 dnd_character.toml 的文本文件中提取的字符串。 这个字符串可能来自任何地方(比如,使用 Requests 模块从网上下载)。 但是由于从 .toml 文件中读取它是如此普遍,所以 tomli.load() 函数可以直接接受文件对象:

import tomli  # import tomllib in Python 3.11
import pprint

with open('dnd_character.toml', 'rb') as fileObj:
  dnd_char = tomli.load(fileObj)
pprint.pprint(dnd_char)

请注意,您传递给的文件对象 tomli.load() 必须以“读取二进制”模式打开,而不仅仅是默认的“读取文本”模式,因此您需要通过 'rb' 作为第二个参数 open() 功能。

不像 json 模块的 dumps() 功能,没有 tomli.dumps() 可以为 TOML 文件创建文本的函数。 这是因为虽然 JSON 意味着人类可读并可由程序读写,但 TOML 文件旨在用于配置文件。 这些文件通常由人类读写,但只能由软件读取。 有一个第三方模块叫做 toml-w 有一个 tomli-w.dumps() 用于编写 TOML 结构文本的函数。 这 dumps() 函数不会是的一部分 tomllib Python 3.11 标准库中的模块。

在文本编辑器中编写 TOML 文件

我们已经介绍了您的 Python 程序如何读取 TOML 文件。 但是当您手动编写 TOML 时,您需要了解 TOML 格式的语法。 幸运的是,Tom’s Obvious, Minimal Language 有一个明显的、极简的格式,很容易记住。 (有关完整详细信息,您可以阅读 TOML 网站上的文档。)

TOML 文件可以包含被解析器忽略的注释。 它们看起来像 Python 注释:以 a 开头 # 并延伸到行尾。 TOML 文件中也允许和忽略空行。

基本键值对的编写方式类似于 Python 赋值语句,键和值由等号分隔:

name = "Mordnilap"
class = "Magic user"
maxHP = 14
currentHP = 2

tomli.loads() 函数采用上面的 TOML 并返回以下 Python 字典:

{'name': 'Mordnilap', 'class': 'Magic user', 'maxHP': 14, 'currentHP': 2}

TOML 有一些大多数编程语言通用的标准数据类型,例如用单引号或双引号括起来的字符串(如 'Mordnilap') 和整数(如 14).

TOML 也有带小数点的浮点数(比如 3.1415 或者 -42.0) 和小写布尔值 truefalse. 注意 truefalse 在 TOML 中的编写方式与 Python 的不同 TrueFalse. TOML 不是特定于 Python 的格式,而是一种可以被许多编程语言解析的通用格式。 在这种情况下,小写 truefalse 类似于JavaScript和JSON的布尔值的写法。

日期和时间也是 TOML 中的一等值; 它们有特定的格式(在 RFC 3339 中有详细说明),您不需要将它们写成用引号括起来的字符串。 有几种不同的写法。 对于包含时区的数据和时间戳,您可以使用 Z 表示 UTC 的后缀。 或者您可以指定与 UTC 的偏移量:

odt1 = 1979-05-27T07:32:00Z  # UTC time zone
odt2 = 1979-05-27T00:32:00-07:00  # UTC minus 7 hours

tomli.loads() 函数采用上面的 TOML 并返回以下 Python 字典:

{'odt1': datetime.datetime(1979, 5, 27, 7, 32, tzinfo=datetime.timezone.utc),
 'odt2': datetime.datetime(1979, 5, 27, 0, 32, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=61200)))}

您还可以在 TOML 中使用数组,例如我们的示例 inventory = ["apple", "enchanted staff", "healing potion"] 生成 Python 字典 {"inventory": ["apple", "enchanted staff", "healing potion"]}. 数组还可以包含其他数组。

TOML 没有字典,而是有可以在方括号表标题下形成的表格:

[Mordnilap]
class = "Magic user"
maxHP = 14
currentHP = 2

[Bilbo]
class = "Fighter"
maxHP = 16
currentHP = 16

tomli.loads() 函数采用上面的 TOML 并返回以下 Python 字典:

{'Bilbo': {'class': 'Fighter', 'currentHP': 16, 'maxHP': 16},
 'Mordnilap': {'class': 'Magic user', 'currentHP': 2, 'maxHP': 14}}

您还可以使用点分符号来创建这些字典。 以下 TOML 生成与前面示例相同的字典:

Mordnilap.class = "Magic user"
Mordnilap.maxHP = 14
Mordnilap.currentHP = 2

Bilbo.class = "Fighter"
Bilbo.maxHP = 16
Bilbo.currentHP = 16

但您也可以在 TOML 中使用更紧凑的内联表:

Mordnilap = { "class" = "Magic user", "maxHP" = 14, "currentHP" = 2 }
Bilbo = { "class" = "Fighter", "maxHP" = 16, "currentHP" = 16 }

您可以在 TOML 文档中阅读 TOML 语法的其他几个方面,但我希望这篇博文已经为您很好地介绍了这个有用的工具,它将成为 Python 标准库的一部分,因为 tomllib 从 3.11 版开始的模块。

阅读更多

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注