tomllib 怎样读取 TOML 配置
来源:17golang原创
时间:2026-10-25 13:41:03 196浏览 收藏
tomllib 读取 TOML 配置时只有两个核心入口:文件用 tomllib.load(),已经在内存中的文本用 tomllib.loads()。前者接收可读取的二进制文件对象,后者接收 str,两者都会返回一个 Python dict。项目使用 Python 3.11 及以后版本时,可以直接导入标准库模块。
官方文档:https://docs.python.org/3/library/tomllib.html
先把输入类型选对:打开 TOML 文件时使用rb,不要把文本文件对象直接传给load;如果配置已经是字符串,就用loads。语法错误由TOMLDecodeError报告,字段缺失则属于解析后的业务校验。
load读取二进制文件对象,loads读取字符串。- TOML 的表、数组、日期和数字会按规则转换到 Python 对象,结果仍需业务代码检查必填字段。
- 先固定输入规模,再用同一测量方法比较读取基线;不要把未经执行的示例数字写成性能结论。
最小写法:文件和字符串分别用 load、loads
文件入口的关键不是函数名本身,而是文件模式。官方接口要求 load 的第一个参数是可读取的二进制文件对象,因此最小写法是 open("config.toml", "rb")。字符串入口则直接把 TOML 文本传给 loads。
import tomllib
# 文件入口必须保持二进制读取,返回值是普通字典。
with open("config.toml", "rb") as config_file:
config = tomllib.load(config_file)
# 文本已经在内存中时,使用 loads;它接收 str 而不是 bytes。
inline_config = tomllib.loads('''
[server]
host = "127.0.0.1"
port = 8080
''')
# 先取表,再取字段;字段是否存在由业务代码决定。
server = config.get("server", {})
host = server.get("host", "127.0.0.1")
port = server.get("port", 8080)
如果配置文件内容与字符串示例相同,两种入口产生的结构都可以按 config["server"]["port"] 读取。示例中的默认值只表示应用层的兜底策略,不是 tomllib 自动补出的字段。

类型转换决定了读取结果长什么样
tomllib 不把所有值都返回字符串。TOML 文档会被转换为字典;字符串、整数、浮点数和布尔值分别对应 str、int、float 和 bool;表与内联表对应 dict,数组对应 list。日期时间还可能得到 datetime、date 或 time。
# 这个文件展示读取后的 Python 类型边界。 name = "demo" retries = 3 ratio = 0.75 enabled = true release-date = 2026-10-25 regions = ["cn", "us"] [database] host = "localhost" port = 5432
import tomllib from decimal import Decimal toml_text = ''' price = 12.50 [database] port = 5432 ''' # parse_float 可以把浮点字面量交给 Decimal,避免业务金额直接使用 float。 config = tomllib.loads(toml_text, parse_float=Decimal) price = config["price"] db_port = config["database"]["port"] # 这里的类型取决于 TOML 写法,不要只按配置字段名称猜测。 print(type(price).__name__, type(db_port).__name__)
parse_float 会接收每个 TOML 浮点数的文本;如果传入 Decimal,读取后的浮点值就会按该类型构造。这个回调不能返回 dict 或 list,否则会引发 ValueError。读取完成后,仍然应该把端口、重试次数等字段转换成应用真正接受的范围。
解析错误和字段缺失不要混在一起处理
文件存在并不代表 TOML 合法。引号没有闭合、表语法写错等问题会在解析阶段抛出 tomllib.TOMLDecodeError;语法合法但缺少 database.host,则属于解析成功后的业务问题。两者的处理动作不同,建议保留原始异常信息,同时对业务字段给出清晰提示。
import tomllib
def read_config(path):
try:
# 只捕获 TOML 语法错误,文件权限等 I/O 错误继续交给上层。
with open(path, "rb") as config_file:
return tomllib.load(config_file)
except tomllib.TOMLDecodeError as exc:
# 解析失败时保留官方异常,便于定位行列位置。
raise ValueError(f"配置文件不是合法 TOML:{exc}") from exc
config = read_config("config.toml")
database = config.get("database")
if not isinstance(database, dict) or "host" not in database:
# 这里是业务字段校验,不要伪装成 TOML 语法错误。
raise ValueError("配置缺少 database.host")
如果要向用户展示错误位置,可以使用异常提供的消息;较新的 Python 文档还列出 msg、doc、pos、lineno 和 colno 属性。不要用字符串比较代替异常类型判断,也不要为了“容错”把所有 ValueError 都吞掉。

用固定输入建立读取基线,再决定是否复用结果
如果同一个配置文件会被多个请求反复读取,先建立基线:固定文件大小、读取次数和 Python 版本,分别记录“每次打开并解析”和“启动时解析一次、后续复用字典”的耗时。下面的代码只提供测量方法,不填入未经执行的毫秒数。
import time
import tomllib
def load_once(path):
# 每次调用都打开并解析,用来定义重复读取基线。
with open(path, "rb") as config_file:
return tomllib.load(config_file)
start = time.perf_counter()
for _ in range(100):
load_once("config.toml")
elapsed = time.perf_counter() - start
# 记录次数、文件大小和 elapsed,而不是把一次机器结果推广给所有环境。
print({"reads": 100, "seconds": elapsed})
配置是进程级静态数据时,通常可以在启动阶段读取一次并复用结果;配置热更新则要明确重新加载时机、并发可见性和失败回退。tomllib 只提供读取,不提供写回 TOML 的 API;需要生成或编辑文件时,应另选写入工具,并重新定义格式保留要求。
读取 TOML 前后的速查清单
- 文件使用
open(path, "rb"),内存字符串使用tomllib.loads(text)。 - 确认 Python 版本满足项目对
tomllib的要求。 - 按类型读取字段,别把日期、数组和表当成普通字符串。
- 将
TOMLDecodeError与必填字段缺失分开提示。 - 反复访问的配置先测量,再选择启动时读取或按需读取。
- 不把
tomllib当作 TOML 写入器,也不把示例代码的输出当成实测结果。
常见问题
tomllib.load 为什么要用 rb 打开?
因为官方接口要求可读取的二进制文件对象。文本已经在内存中时,不要绕过文件模式去猜测,直接使用 tomllib.loads。
tomllib 能不能修改并保存 TOML?
不能。它是标准库中的 TOML 读取模块,不提供写入接口。读取后的字典可以在内存中修改,但要保存回 TOML,需要另选写入方案并考虑格式保留。
字段不存在应该捕获 TOMLDecodeError 吗?
不应该。语法错误由 TOMLDecodeError 表示;字段缺失发生在解析成功之后,应由业务校验处理。
-
369 收藏
-
344 收藏
-
464 收藏
-
327 收藏
-
184 收藏
-
137 收藏
-
446 收藏
-
337 收藏
-
161 收藏
-
218 收藏
-
115 收藏
-
254 收藏
-
320 收藏
-
118 收藏
-
372 收藏
-
文章 · python教程 | 1小时前 | 异常处理 · python · 异步编程 · asyncio · 超时处理 CancelledError Python异步 asyncio.timeout TimeoutError433 收藏
-
396 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习