6 次浏览0 条回复

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。把原始字典转换为不可变的数据类后,业务代码不再需要反复处理缺失键和动态类型。