Python 配置文件格式选型对比分析

1次阅读

toml 更适合现代 python 项目配置,因其被 poetry、setuptools、black 等工具原生支持,且 tomllib(3.11+)或 tomli 支持布尔、数组、内联表等结构;ini 虽标准库原生支持,但语法僵硬、无嵌套、不兼容主流工具链。

Python 配置文件格式选型对比分析

INI 和 TOML 哪个更适合 Python 项目配置?

Python 项目里配 config.ini 还是 pyproject.toml,不是风格问题,是读写逻辑和工具链适配问题。标准库原生支持 configparser 读 INI,但不支持 TOML;而现代工具(如 poetrysetuptools)默认只认 TOML。选错格式,轻则自己多写解析逻辑,重则和依赖工具冲突。

  • configparser 对 INI 的“节”(section)和键值对有严格语法要求:等号前后不能有空格、注释必须用 ;# 开头且独占一行、不支持嵌套或数组
  • TOML 用 tomllib(Python 3.11+ 内置)或 tomli(兼容旧版)读取,天然支持布尔、日期、数组、内联表,比如 features = ["auth", "Logging"] 直接解析成 list
  • 如果项目要接入 blackisortmypy,它们都从 pyproject.toml 读配置——硬用 INI 就得额外桥接,徒增 setup.cfg 或环境变量中转

json 配置在 Python 里为什么很少见?

json 模块虽是标准库,但 JSON 不是为配置设计的:没注释、不支持尾逗号、字符串必须双引号、无法表达 Python 特有类型(如 NoneTrue)。硬用 JSON 做配置,会反复遇到这些卡点:

  • 修改配置时加个注释就得删掉再重写,CI 流水线里容易因格式报错中断
  • None 写成 NULL 是合法的,但某些 Python 库(如 argparse 的扩展)会期望原生 None,中间转换易出错
  • 路径字段如 "log_path": "/var/log/app",在 windows 上手动改斜杠容易漏,而 TOML 的多行字符串或 INI 的变量展开(%(home)s/logs)更稳

YAML 看起来灵活,但实际踩坑最多

PyYAML 默认启用 unsafe load,yaml.load(input) 可执行任意代码——很多线上漏洞就源于此。哪怕改成 yaml.safe_load(),还有几个隐性麻烦:

  • 缩进敏感,空格/Tab 混用直接抛 ScannerError
  • 时间字符串(如 2023-01-01)会被自动转成 datetime 对象,而你可能只想当普通字符串用
  • 键名含连字符(如 api-key)会被解析成字典 key,但 Python 访问时得写 cfg["api-key"],没法用点号访问,和大多数 Python 配置类习惯冲突

Python 原生 .py 文件做配置到底靠不靠谱?

把配置写成 config.py,用 import config 直接加载,确实最“Pythonic”,也支持任意表达式(比如动态生成 Token)。但它绕过了所有配置校验机制:

立即学习Python免费学习笔记(深入)”;

  • 没法做 schema 校验,拼错变量名(如 DEBUB = True)直到运行时报 NameError 才发现
  • 无法被非 Python 工具消费,CI 中用 shell 脚本预检配置就失效
  • 若配置里调用了外部函数或读了环境变量,测试时容易污染全局状态;而 TOML/INI 是纯数据,可安全 mock

配置格式不是越新越好,也不是越通用越好。关键看谁读、怎么读、改得多不多。TOML 在新项目里基本是首选,但老系统还在用 INI,就别强行迁移——configparser 跑十年没出过解析 bug,而换格式后手写的 TOML parser 可能下周就崩。

text=ZqhQzanResources