[译]Python 和 TOML:新最好的朋友 (1) 了解TOM

文章目录

  • Python 和 TOML:新最好的朋友
  • 使用TOML作为配置文件
    • 配置和配置文件
    • TOML: Tom’s Obvious Minimal Language
    • TOML 模式验证
  • 了解TOML:键值对
    • Strings, Numbers, and Booleans
    • Tables
    • Times and Dates
    • Arrays

在这里插入图片描述

Python 和 TOML:新最好的朋友

原文:《Python and TOML: New Best Friends》

toml

TOML(Tom’s Obvious Minimal Language)是一种相当新的配置文件格式。Python社区在过去几年中已经接受了它,许多流行的工具都使用TOML 进行配置,您将在构建和分发自己的包时可能就会使用 pyproject.toml

使用TOML作为配置文件

TOML最初目标是成为一种易于人类阅读和编写的配置文件格式。

之前,已经有了许多配置文件格式,如JSON、YAML、INI等。但是它们不是很适合人类读写。JSON多层嵌套时,很难阅读。YAML的缩进可能很混乱。INI没有同一的规范,且只适合简单的配置。
–《https://zhuanlan.zhihu.com/p/50412485》

配置和配置文件

几乎任何程序都需要配置。例如,使用配置文件指定数据库信息。
为项目使用配置文件是将代码与其设置分开的好方法。
现在,考虑一个井字游戏的配置文件

player_x_color = blue
player_o_color = green
board_size     = 3
server_url     = https://tictactoe.example.com/

您可以直接在源代码中对此进行编码。但通过单独的配置文件可以实现以下几点:

  • 为值提供显式名称
  • 为这些值提供更多的可见性
  • 使值更容易更改

仔细观察这些配置,可能会发现这些配置需要分成不同部分:
color信息可能是用户配置的,而board_size可能是固定的,server_url是服务器相关的。
一种选择是将配置分成多个文件,另一种是进行分组

[user]
player_x_color = blue
player_o_color = green[constant]
board_size = 3[server]
url = https://tictactoe.example.com

文件的组织使每个配置项的角色更加清晰。您还可以向配置文件添加注释使得配置项更更加清晰。

TOML: Tom’s Obvious Minimal Language

TOML是一种相当新的格式。第一个格式规范 0.1.0 版于 2013 年发布。从一开始,它就专注于成为人类可读的最小配置文件格式。TOML文档描述其目标如下:

TOML旨在成为一种最小的配置文件格式,语义明显,易于阅读。TOML 旨在明确映射到哈希表。TOML应该很容易解析为各种语言的数据结构。

TOML非常流行,越来越多的 Python 工具(包括 Black、pytest、mypy 和 isort)使用 TOML 进行配置。

回想一下上一小节中的配置。
在TOML中表达它的方式如下

[user]
player_x.color = "blue"
player_o.color = "green"[constant]
board_size = 3[server]
url = "https://tictactoe.example.com"

TOML 模式验证

在实践中,给定的 TOML 文件也可能带有一些非语法要求。
这些是架构要求(schema requirements)。例如,井字游戏应用程序可能要求配置文件包含server URL。另一方面,player color可能是可选的,因为应用程序定义了默认颜色。

目前,TOML不包含可以在TOML文档中指定必需和可选字段的架构语言。存在几个提案,尽管目前尚不清楚是否会很快接受其中任何一个。

在简单的应用程序中,您可以手动验证 TOML 配置。例如,您可以使用 Python 3.10 中引入的结构模式匹配(Structural Pattern Matching)。假设您已将配置解析为 Python 并将其命名为 config 。然后,您可以按如下方式检查其结构:

match config:case {"user": {"player_x": {"color": str()}, "player_o": {"color": str()}},"constant": {"board_size": int()},"server": {"url": str()},}:passcase _:raise ValueError(f"invalid configuration: {config}")

第一个 case 语句阐明了您期望的结构。如果 config 匹配,则用于 pass 继续代码。否则,将引发错误。

如果您的 TOML 文档更复杂,则此方法可能无法很好地扩展。如果你想提供良好的错误消息,你还需要做更多的工作。更好的选择是使用 pydantic,它利用类型注释在运行时进行数据验证。pydantic 的一个优点是它内置了精确且有用的错误消息。

还有一些工具可以利用 JSON 等格式的现有架构验证。例如,Taplo 是一个 TOML 工具包,可以根据 JSON 模式验证 TOML 文档。Taplo 也可用于 Visual Studio Code,捆绑在 Even Better TOML 扩展中。

了解TOML:键值对

TOML 是围绕键值对构建的,这些键值对很好地映射到哈希表数据结构。TOML 值具有不同的类型。每个值可以使以下类型之一:

  • 字符串
  • 整数
  • 浮点数
  • 布尔值
  • 日期和时间
  • 数组
  • 内联表

此外,还可以将table 和array of tables作为集合来组织多个键值对。您将在本节的其余部分了解有关所有这些内容的更多信息,以及如何在 TOML 中指定它们。

注:TOML 支持与 Python 语法相同的注释(#)。

如前所述,键值对是 TOML 文档中的基本构建块。您可以使用 <key> = <value> 语法:

greeting = "Hello, TOML!"

在此示例中, greeting 是键,而 "Hello, TOML!" 是值。
值具有类型。在此示例中,该值是一个文本字符串。
键始终被解释为字符串,即使不用引号括起来也是如此。请看以下示例:

greeting = "Hello, TOML!"
42 = "Life, the universe, and everything"

此处42是一个 有效的键,它被解释为字符串,而不是数字。通常,您希望使用裸键。这些键仅由 ASCII 字母和数字以及下划线和破折号组成。所有这些键都可以不带引号地编写,如上面的示例所示。

TOML 文档必须以 UTF-8 Unicode 编码。这为您提供了极大的灵活性,可以代表各种值。
您也可以在键中使用 Unicode。若要使用 Unicode 键,必须在它们两边添加引号:

"realpython.com" = "Real Python"
"blåbærsyltetøy" = "blueberry jam"
"Tom Preston-Werner" = "creator"

点(.)在 TOML 键中起着特殊作用。您可以在不带引号的键中使用点,在这种情况下,它们将通过拆分每个点的点键来触发分组

player_x.symbol = "X"
player_x.color = "purple"

在这里,您指定两个点键(dotted key)。由于它们都以 player_x 开头,因此键 symbol 和 color 将组合在名为 player_x 的部分中。当您开始浏览表时,您将了解有关点键的更多信息。

接下来,将注意力转向值。在下一节中,您将了解 TOML 中最基本的数据类型。

Strings, Numbers, and Booleans

TOML 对基本数据类型使用熟悉的语法。来自Python的您能够识别字符串、整数、浮点数和布尔值:

string = "Text with quotes"
integer = 42
float = 3.11
boolean = true

TOML 和 Python 之间的直接区别在于 TOML 的布尔值是小写的: truefalse

TOML 字符串通常应使用双引号,并可以用反斜杠(\)转义字符。
还可以使用单引号指定字符串。单引号字符串称为文字字符串,其行为类似于 Python 中的原始字符串
最后,还可以使用三引号"""''' )指定字符串。三引号字符串允许您在多行上编写字符串,类似于 Python 多行字符串

partly_zen = """
Flat is better than nested.
Sparse is better than dense.
"""

TOML 中的数字可以是整数,也可以是浮点数。整数表示整数,并指定为纯数字字符。与 Python 一样,您可以使用下划线来增强可读性:

number = 42
negative = -8
large = 60_481_729

Tables

您已经了解了 TOML 文档由一个或多个键值对组成。当用编程语言表示时,它们应存储在哈希表数据结构中。在 Python 中,这将是一个字典或其他类似字典的数据结构。要组织键值对,您可以使用

TOML 支持三种不同的表指定方式。

  • 在大多数情况下,使用带有标头的常规表
  • 当您需要指定几个与其父表密切相关的键值对时,请使用点键表
  • 仅对具有最多三个键值对的非常小的表使用内联表,其中数据构成明确定义的实体。
[user]
player_x.color = "blue"
player_o.color = "green"[constant]
board_size = 3[server]
url = "https://tictactoe.example.com"

在此示例中,您有三个表:user、constant 和 server。每个表都有一个标头,用方括号括起来。

您还可以在上面的配置中找到点键表(dotted key tables)。在 user中:

[user]
player_x.color = "blue"
player_o.color = "green"

键中的点 (.)创建一个由点之前的键部分命名的表(player_x)。您还可以通过嵌套常规表实现相同效果:

[user][user.player_x]color = "blue"[user.player_o]color = "green"

缩进在 TOML 中并不重要。您可以在此处使用它来表示表的嵌套。您可以看到该 user 表包含两个子表, player_x 以及 player_o 。每个子表都包含一个键值对。

请注意,您需要在嵌套表的标头中使用点键,并命名所有中间表。这使得 TOML 标头规范非常冗长。在类似的规范中,例如 JSON 或 YAML,您只需指定子表名称,而不重复外部表的名称。同时,这使得 TOML 非常明确,并且更难在深度嵌套的结构中迷失方向。

现在,您将通过为每个玩家添加标签或符号来扩展 user 表格。您将以三种不同的形式表示此表,首先仅使用常规表,然后使用点键表,最后使用内联表。

常规表

[user][user.player_x]symbol = "X"color = "blue"[user.player_o]symbol = "O"color = "green"

点键表

[user]
player_x.symbol = "X"
player_x.color = "blue"
player_o.symbol = "O"
player_o.color = "green"

这比上面的嵌套表更短、更简洁。但是,结构现在不太清晰。

内联表

[user]
player_x = { symbol = "X", color = "blue" }
player_o = { symbol = "O", color = "green" }

内联表使用大括号 {}定义,这些大括号 用逗号分隔的键值对换行。在此示例中,内联表在可读性和紧凑性之间取得了很好的平衡,因为玩家表的分组变得清晰。

TOML 文档由一个无名根表(root table)表示,该根表包含所有其他表和键值对。在 TOML 配置顶部(在任何表头之前)写入的键值对直接存储在根表中:

title = "Tic-Tac-Toe"[constant]
board_size = 3

在此示例中, title 是根表中的键, constant 是嵌套在根表中的表,board_sizeconstant表中的键。

请注意,表包含在其标头和下一个表标头之间写入的所有键值对。在实践中,这意味着您必须在属于该表的键值对下方定义嵌套子表。请考虑以下文档:

[user][user.player_x]color = "blue"[user.player_o]color = "green"background_color = "white"

(看上去)缩进表明这应该 background_coloruser 表中的键。但事实上,TOML 会忽略缩进,只检查表头。在此示例中, background_coloruser.player_o表的一部分。要更正此问题, background_color 应在嵌套表之前定义:

[user]
background_color = "white"[user.player_x]color = "blue"[user.player_o]color = "green"

Times and Dates

TOML 有四种日期和时间类型:

  • offset date-time:偏移日期时间是带有时区信息的时间戳,表示特定时刻。
  • local date-time:本地日期时间是不带时区信息的时间戳。
  • local date :没有时区信息的日期
  • local time: 时间

TOML 基于 RFC 3339 表示时间和日期。本文档定义了一种时间和日期格式,该格式通常用于表示 Internet 上的时间戳。完全定义的时间戳如下所示: 2021-01-12T01:23:45.654321+01:00。时间戳由多个字段组成,由不同的分隔符分隔。

2021-01-12T01:23:45.654321+01:00对应的含义为:
年-月-日T时:分:秒.微秒+时区与UTC的偏移量
其中T可以用空格替换,微秒是可选的,偏移量可用Z表示与UTC时间相同。

Arrays

TOML数组是值的有序列表,可用[]创建,类似Python的列表。

packages = ["tomllib", "tomli", "tomli_w", "tomlkit"]
players = [{ symbol = "X", color = "blue", ai = true },{ symbol = "O", color = "green", ai = false },
]

您可以将内联表放在方括号内。但是内联表不能很好地扩展。如果要表示表较大的表数组,则可以考虑表数组

[[players]]
symbol = "X"
color = "blue"
ai = true[[players]]
symbol = "O"
color = "green"
ai = false

表数组等效于您上面编写的内联表数组。方括号双括号定义表数组,而不是常规表。

对于更广泛的示例,请考虑以下摘录自 TOML 文档,其中列出了测验应用程序的问题:

[python]
label = "Python"[[python.questions]]
question = "Which built-in function can get information from the user"
answers = ["input"]
alternatives = ["get", "print", "write"][[python.questions]]
question = "What's the purpose of the built-in zip() function"
answers = ["To iterate over two or more sequences at the same time"]
alternatives = ["To combine several strings into one","To compress several files into one archive","To get information from the user",
]

此例中,python表包含两个键:labelquestionsquestions 键是一个表数组,其中每个元素都是一个表。每个questions 表都包含question, answersalternatives

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/534825.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

12 list的使用

文档介绍 文档介绍 1.list是可以在常数范围内的任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代 2.list的底层是带头双向链表循环结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和…

【安装jupyter依赖nbconvert后,jupyter还是找不到nbconvert】打开jupyter notebook报错500:Internal Server Error

文章目录 1. 一般是缺少依赖项或配置问题1.1.检查运行环境&#xff1a;1.2. 安装nbconvert。1.3.jupyter --version查看还是没有&#xff0c;卸载重新安装。1.4. 还有安装&#xff0c;继续卸载重新安装1.4.1.如果删除后还是报已经存在&#xff0c;删除对应文件夹 1.5.jupyter -…

【Java - 框架 - Mybatis】(01) 普通Java项目使用Mybatis操作Mysql - 快速上手

普通Java项目使用Mybatis操作Mysql - 快速上手 说明 通过软件"IntelliJ IDEA"创建"Maven"项目完成&#xff1b;通过"Mybatis"框架操纵"MySQL"数据库完成操作&#xff1b; 环境 Java版本"1.8.0_202"&#xff1b;Windows …

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的商品识别系统(深度学习+UI界面+训练数据集+Python代码)

摘要&#xff1a;在零售行业的技术进步中&#xff0c;开发商品识别系统扮演着关键角色。本博文详细阐述了如何利用深度学习技术搭建一个高效的商品识别系统&#xff0c;并分享了一套完整的代码实现。系统采用了性能强劲的YOLOv8算法&#xff0c;同时对YOLOv7、YOLOv6、YOLOv5等…

Docker部署系列之Docker Compose安装Redis三主三从集群

在日常开发或者编程当中&#xff0c;经常需要用到redis集群&#xff0c;若是按照传统的方式&#xff0c;一个机器一个机器搭建&#xff0c;难免过于繁琐&#xff0c;故而可以通过dock er-compose编排方式&#xff0c;快速搭建。我在搭建过程当中&#xff0c;将操作记录下来&…

TS271IDT运算放大器芯片中文资料PDF数据手册引脚图图片参数价格功能

产品描述&#xff1a; TS271 是一款低成本、低功耗的单通道运算放大器&#xff0c;设计用于采用单电源或双电源供电。该运算放大器采用意法半导体硅栅CMOS工艺&#xff0c;具有出色的消耗-速度比。该放大器非常适合低功耗应用。 电源可通过引脚 8 和 4 之间连接的电阻器进行外…

如何只用pycharm创建venv虚拟环境

如何只用pycharm创建venv虚拟环境 网上貌似没有好的博客讲解&#xff0c;我之前也一直在这环境搭建上疑惑。不过照着我这博客来&#xff0c;应该没问题了。 前言 如图所示&#xff0c;我新建了一个空白文件夹。 接下来点击终端&#xff08;AltF12&#xff09; 如果发现开头…

Java异常分类(二)

RuntimeException 运行时异常&#xff1a; 派生于 RuntimeException 的异常&#xff0c;如被 0 除、数组下标越界、空指针等&#xff0c;其产生比较频繁&#xff0c;处理麻烦&#xff0c;如果显式的声明或捕获将会对程序可读性和运行效率影响很大。因此由系统自动检测并将它们交…

Docker 笔记(四)--网络

这篇笔记写的时间很久&#xff0c;记录了Docker 的网络知识&#xff0c;概念从浅入深&#xff0c;对docker网络有一个大体介绍&#xff0c;对部分细节做了详细解析&#xff0c;但涉及的知识点太多&#xff0c;未能在一篇中全部罗列&#xff0c;后续逐步完善吧。 目录 参考环境网…

算法归纳【数组篇】

目录 二分查找1. 前提条件&#xff1a;2. 二分查找边界 2.移除元素有序数组的平方长度最小的子数组59.螺旋矩阵II54. 螺旋矩阵 二分查找 参考链接 https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html#%E6%80%9D%E8%B7%AF 1. 前提条件&#xff1a; 数…

C#类的应用实例1-石头剪刀布

C#类的应用非常广泛&#xff0c;可以用于各种软件开发项目&#xff0c;包括但不限于以下几个方面&#xff1a; 桌面应用程序开发&#xff1a;C#类可用于开发Windows桌面应用程序&#xff0c;如图形用户界面&#xff08;GUI&#xff09;应用程序、数据库应用程序等。通过定义类和…

蓝桥杯 填空 卡片

蓝桥杯 填空题 卡片 解题思路&#xff1a; 我们只需要消耗完卡片的个数即可。 代码示例&#xff1a; #include<bits/stdc.h> using namespace std; int a[10]; bool isEnd(){for(int i0;i<10;i){if(a[i]-1)return false;}return true; } bool getN(int x){while(x){i…