Python 3.11 起可以用标准库 tomllib 读取 TOML。解析成功只代表语法正确,配置的必填项、类型和取值范围仍应在入口处显式校验。
环境:Python 3.11+;Linux、macOS 或 Windows;无第三方依赖。
创建 app.toml:
[app]
port = 8080
debug = false
创建 config.py:
from dataclasses import dataclass
from pathlib import Path
import tomllib
@dataclass(frozen=True)
class AppConfig:
port: int
debug: bool
def load_config(path: Path = Path("app.toml")) -> AppConfig:
with path.open("rb") as file:
raw = tomllib.load(file)
app = raw.get("app")
if not isinstance(app, dict):
raise ValueError("missing [app] table")
port = app.get("port")
debug = app.get("debug", False)
# bool 是 int 的子类,需要单独排除。
if isinstance(port, bool) or not isinstance(port, int):
raise ValueError("app.port must be an integer")
if not 1 <= port <= 65535:
raise ValueError("app.port must be between 1 and 65535")
if not isinstance(debug, bool):
raise ValueError("app.debug must be a boolean")
return AppConfig(port=port, debug=debug)
if __name__ == "__main__":
print(load_config())
运行:
python config.py
预期输出:
AppConfig(port=8080, debug=False)
这里使用二进制模式打开文件,因为 tomllib.load() 接收二进制文件对象。另一个容易忽略的细节是 isinstance(True, int) 为真;只检查 int 会错误地接受 port = true。把原始字典转换为不可变的数据类后,业务代码不再需要反复处理缺失键和动态类型。