Python 3.11+:用 tomllib 读取 pyproject.toml 的配置

43 次浏览4 条回复

如果脚本只需要读 pyproject.toml 里的少量配置,Python 3.11 起可以直接用标准库 tomllib,不用再装 TOML 解析依赖。

环境:Python 3.11+。建个最小例子:

mkdir tomllib-demo && cd tomllib-demo
printf '[tool.demo]
name = "sample"
workers = 2
' > pyproject.toml
printf 'import tomllib

with open("pyproject.toml", "rb") as f:
    config = tomllib.load(f)

print(config["tool"]["demo"]["name"])
print(config["tool"]["demo"]["workers"])
' > read_config.py
python read_config.py

tomllib.load() 要求以二进制模式打开文件;如果手里已经是字符串,也可以用 tomllib.loads()。它只负责解析,不会替你校验业务字段,配置缺失时还是要在代码里给默认值或报清楚。

补一个兼容性小点:如果项目还要支持 Python 3.10 及以下,可以把第三方 tomli 当成回退;3.11+ 再直接导入 tomllib。这样配置读取这层不用为了兼容版本分两套逻辑。

隔壁空白Lv1#1

补一个兼容性小点:如果项目还要支持 Python 3.10 及以下,可以把第三方 tomli 当成回退;3.11+ 再直接导入 tomllib。这样配置读取这层不用为了兼容版本分两套逻辑。

再补个容易踩到的点:脚本从别的目录启动时,open("pyproject.toml") 是按当前工作目录找的。想固定读项目文件,可以写成:

from pathlib import Path
path = Path(__file__).with_name("pyproject.toml")
with path.open("rb") as f:
    config = tomllib.load(f)

做成命令行工具时会省掉不少“文件明明在这却找不到”的情况。

Nathan03Lv1#2

再补个容易踩到的点:脚本从别的目录启动时,open("pyproject.toml") 是按当前工作目录找的。想固定读项目文件,可以写成:

from pathlib import Path
path = Path(__file__).with_name("pyproject.toml")
with path.open("rb") as f:
    config = tomllib.load(f)

做成命令行工具时会省掉不少“文件明明在这却找不到”的情况。

还有一点:tomllib 遇到格式错误会抛 tomllib.TOMLDecodeError,做启动配置时最好把文件路径带进错误信息;不然用户只看到解析失败,定位起来有点费劲。它也只能读 TOML,修改配置还是得用别的库或自己生成。

Zoe_JayLv1#3

还有一点:tomllib 遇到格式错误会抛 tomllib.TOMLDecodeError,做启动配置时最好把文件路径带进错误信息;不然用户只看到解析失败,定位起来有点费劲。它也只能读 TOML,修改配置还是得用别的库或自己生成。

对,pyproject.toml 里的自定义配置最好放在自己的 tool.<项目名> 命名空间下,别把字段直接塞到顶层。这样既不容易和构建工具的标准字段撞名,后面换构建后端时也更稳。读取后再做一次必填字段和类型校验,解析成功不代表业务配置一定完整。