当前位置: 首页 > news >正文

Python常用模块:.ini、.yaml、.toml

一、.ini

一个ini文件由多个段section组成,每个段的名字都是自定义的,每个段section中以key=vlaue的形式组成。

importosimportconfigparser config_path=os.path.join(os.path.dirname(__file__),'config/config.ini')print(config_path)config=configparser.ConfigParser()config.read(config_path,encoding='utf-8')# 读取方式一url=config['login']['url']# 读取方式二,get读取的是strusername=config.get('login','username')port=config.getint('mysql','port')times=config.getfloat('common','times')is_dev=config.getboolean('login','dev')# 读取所有段sections=config.sections()# 读取一个sectionmysql_list=config.items('mysql')# 添加一个段config.add_section('result')config.set('result','success','true')config.write(open(config_path,mode='w'))

二:YAML

> 换行→空格,末尾保留 1 个 \n | 保留换行原样 >- 换行→空格,去掉末尾换行(chomp)

经验法则:写自然语言段落型 prompt 用 >;写 few-shot、JSON 模板、需要换行的指令用 |。

# llm-config.yamlmodel:provider:anthropicname:claude-opus-4-7temperature:0.7max_tokens:4096# system prompt:用 > 折叠,写起来像段落,发给模型时是一行system_prompt:>你是一个专业的代码评审助手,擅长 Python、TypeScript 和 Go。 评审时关注:安全漏洞、性能问题、代码可读性。 始终用中文回复,并给出具体的修改建议。# user prompt 模板:保留换行用 |,因为 few-shot 示例需要分行prompt_template:|问题:{question}请按以下步骤回答: 1. 理解问题 2. 给出方案 3. 提供代码示例# 较长的描述用 >- (去掉末尾换行)description:>-这是一个面向企业内部的 RAG 问答系统, 接入公司知识库,支持多轮对话和引用溯源。
importyamlfromutils.path_toolimportget_abs_pathdefload_rag_config(config_path:str=get abs_path("config/agent.yml"),encoding:str="utf-8"):withopen(config_path,"r",encdding=encoding)asf:returnyaml.load(f,Loader=yaml.FullLoader)

三、.toml

1. TOML 是什么?

TOML(Tom’s Obvious, Minimal Language)是一种为人类阅读优化的配置文件格式。它的设计目标只有一句话:写起来像 INI 一样直观,读起来比 JSON 更友好,结构上比 YAML 更不容易踩坑。如果你写过 Rust 的Cargo.toml、Python 的pyproject.toml、Hugo 的config.toml,那么你已经在用它了。近几年 TOML 几乎成为新一代工具链的"事实标准配置格式"。

JSON、YAML、INI 都有一定的缺点,TOML 在这三者之间找到了平衡点:规则少、类型明确、对人友好、对机器无歧义

格式痛点
JSON不能写注释;逗号、引号严苛;不适合人写
YAML缩进敏感;同一份文件可能被解析成多种含义;规范过于复杂
INI没有统一规范;不支持嵌套、数组、类型


2. 文件基本约定

  • 文件后缀:.toml
  • 编码:必须是UTF-8
  • 大小写敏感
  • 行尾换行符 LF (\n) 或 CRLF (\r\n) 都允许
  • 空白与缩进无意义(这是和 YAML 最大的区别)
  • 注释以#开头,可写在行首或行尾
# 这是一行注释 title = "TOML 示例" # 行尾注释也允许

3. 键值对(Key/Value)

TOML 的最小单位是键值对

key = "value"

规则:

  1. 一行只能写一个键值对
  2. 等号两侧的空格可有可无
  3. 值必须是合法的 TOML 类型(下文详述)
  4. 每个键必须有值——没有"裸键"或"空值"这种概念

3.1 键名(Keys)的三种写法

# 1. 裸键(Bare Key):只允许 A-Z a-z 0-9 _ - name = "Alice" user_id = 42 api-key = "xxx" # 2. 字符串键(Quoted Key):用 " 或 ' 包起来,可以包含任意字符 "127.0.0.1" = "localhost" "中文键" = "也合法" 'literal key' = "原样字符串作键名" # 3. 点分键(Dotted Key):用 . 创建嵌套结构,等价于嵌套表 server.host = "localhost" server.port = 8080 # 等价于: # [server] # host = "localhost" # port = 8080

⚠️注意:同一个键不能在同一作用域里被重复定义,否则解析器报错。


4. 字符串(String)

TOML 提供4 种字符串,对应"是否多行"和"是否转义"两个维度:

单行多行
基本(支持转义)"...""""..."""
字面量(原样)'...''''...'''

4.1 基本字符串

用双引号包围,支持常见转义字符:

greeting = "Hello\tWorld\n" path = "C:\\Users\\Alice" emoji = "❤" # ❤

支持的转义序列:\b \t \n \f \r \" \\ \uXXXX \UXXXXXXXX

4.2 多行基本字符串

description = """ 这是一段 多行文本, 开头的换行会被自动去掉。\ 反斜杠+换行可以续行,\ 所以这一段最终是一行。 """

4.3 字面量字符串(推荐写正则、Windows 路径)

用单引号,不解释任何转义

regex = '\d{3}-\d{4}' # 不需要写成 '\\d{3}-\\d{4}' windows_path = 'C:\Users\Alice' # 反斜杠原样保留

4.4 多行字面量字符串

sql = ''' SELECT * FROM users WHERE name = 'Alice' '''

5. 数字与布尔

5.1 整数(Integer)

int1 = 99 int2 = -17 int3 = +42 int4 = 1_000_000 # 下划线分隔,提升可读性 hex = 0xDEADBEEF oct = 0o755 bin = 0b11010110

5.2 浮点数(Float)

flt1 = 3.14 flt2 = -0.001 flt3 = 1e10 flt4 = 6.626e-34 flt5 = 1_000.123_456 # 同样支持下划线分隔 # 特殊值 inf = inf ninf = -inf nan = nan

5.3 布尔(Boolean)

只有两个值,必须小写

enabled = true debug = false

6. 日期与时间

TOML 是少数原生支持日期类型的配置格式,遵循 RFC 3339:

# 1. 带时区的日期时间(Offset Date-Time) dt1 = 2026-05-08T14:30:00+08:00 dt2 = 2026-05-08T06:30:00Z # Z 表示 UTC # 2. 本地日期时间(Local Date-Time, 不带时区) dt3 = 2026-05-08T14:30:00 # 3. 仅日期(Local Date) d = 2026-05-08 # 4. 仅时间(Local Time) t = 14:30:00.123

不需要任何引号包围——这是 TOML 与 JSON/YAML 最显著的差异之一。


7. 数组(Array)

数组用方括号[],元素间逗号分隔:

ports = [80, 443, 8080] hosts = ["alpha", "beta", "gamma"] mixed_ok = [1, 2, 3] # 推荐:同质类型 mixed_too = [1, "two", 3.0, true] # 也允许:TOML 1.0 起放宽了限制 # 多行数组,允许尾随逗号 contributors = [ "Alice <alice@example.com>", "Bob <bob@example.com>", "Carol <carol@example.com>", # 尾随逗号合法 ] # 嵌套数组 matrix = [[1, 2], [3, 4], [5, 6]]

8. 表(Table):TOML 的灵魂

表(Table)就是其他语言里的对象、字典、Map。它是 TOML 表达嵌套结构的核心机制。

8.1 标准表

[表名]声明,之后所有键值对都属于这个表,直到下一个表头出现:

title = "全局键放在最前面" [database] host = "localhost" port = 5432 user = "admin" [server] bind = "0.0.0.0" port = 8080

等价于 JSON:

{"title":"全局键放在最前面","database":{"host":"localhost","port":5432,"user":"admin"},"server":{"bind":"0.0.0.0","port":8080}}

💡最佳实践:所有"裸键值对"都写在文件最顶部,表头之后的内容全部归属对应表。如果把全局键写在表头下面,会被错误地划进那个表。

8.2 嵌套表(点分表名)

[servers.alpha] ip = "10.0.0.1" role = "frontend" [servers.beta] ip = "10.0.0.2" role = "backend"

等价于:

{"servers":{"alpha":{"ip":"10.0.0.1","role":"frontend"},"beta":{"ip":"10.0.0.2","role":"backend"}}}

8.3 内联表(Inline Table)

适合短小、扁平的对象,类似 JSON 风格:

point = { x = 1, y = 2 } person = { name = "Alice", age = 30 } # 内联表必须写在一行内,不能跨行,且一旦写完就"封闭"—— # 不能再用 person.email = "..." 往里面追加键

等价于:

{"point":{"x":1,"y":2},"person":{"name":"Alice","age":30}}

9. 表数组(Array of Tables)

要表达"一组同构对象"(比如多个用户、多个依赖、多个产品),用双方括号[[...]]

[[products]] name = "Hammer" sku = 738594937 [[products]] name = "Nail" sku = 284758393 color = "gray" [[products]] name = "Saw" sku = 192847465

等价于:

{"products":[{"name":"Hammer","sku":738594937},{"name":"Nail","sku":284758393,"color":"gray"},{"name":"Saw","sku":192847465}]}

每出现一次[[products]],就向products数组里追加一个新元素。

表数组里的子表

[[users]] name = "Alice" [users.address] city = "Beijing" zip = "100000" [[users]] name = "Bob" [users.address] city = "Shanghai" zip = "200000"

等价于:

{"users":[{"name":"Alice","address":{"city":"Beijing","zip":"100000"}},{"name":"Bob","address":{"city":"Shanghai","zip":"200000"}}]}

子表的缩进仅为可读性,TOML 不要求缩进。但子表头必须写在对应的[[users]]之后、下一个[[users]]之前,否则归属会错。


10. 一份"贴近实战"的完整示例

# =========================== # myapp.toml — 应用配置示例 # =========================== title = "MyApp" version = "1.2.0" [owner] name = "Alice Wang" dob = 1990-07-15T09:00:00+08:00 [database] host = "127.0.0.1" port = 5432 connection_max = 100 enabled = true allowed_ips = ["10.0.0.1", "10.0.0.2", "10.0.0.3"] [database.credentials] user = "admin" password = "s3cret" [logging] level = "info" outputs = ["stdout", "file"] file = { path = "/var/log/myapp.log", max_size_mb = 100 } [[features]] name = "dark-mode" enabled = true [[features]] name = "beta-search" enabled = false rollout = 0.05 [[servers]] name = "alpha" ip = "10.0.0.1" [[servers]] name = "beta" ip = "10.0.0.2"

11、容易踩的 5 个坑

1. 全局键被误归到表里

[server] host = "localhost" title = "MyApp" # ❌ 这个 title 会被解析成 server.title

✅ 修复:把全局键移到所有表头之上。

2. 重复定义同一张表

[server] host = "a" [server] # ❌ 报错:server 被定义两次 host = "b"

✅ TOML 禁止重复定义同名标准表。如果想要多个,用[[...]]表数组。

3. 内联表不可"事后追加"

point = { x = 1, y = 2 } point.z = 3 # ❌ 报错:内联表声明后即封闭

✅ 修复:要么写完整{ x = 1, y = 2, z = 3 },要么改用标准表[point]

4. 字符串混淆

path = "C:\Users\Alice" # ❌ \U 会被当作 Unicode 转义,通常报错

✅ 修复:用字面量字符串'C:\Users\Alice',或转义"C:\\Users\\Alice"

5. 日期不要加引号

created = "2026-05-08" # ⚠️ 这是字符串,不是日期 created = 2026-05-08 # ✅ 这才是 TOML 的 Local Date 类型

如果下游程序按"日期"类型读取,引号版本会拿到字符串,导致类型错误。


12、TOML vs JSON vs YAML 速查

维度TOMLJSONYAML
注释##
缩进敏感✅(最大坑点)
原生日期类型✅(但跨实现不一致)
数字下划线分隔1_000_000
多种字符串语法✅(4 种)❌(仅一种)✅(多种)
跨实现一致性低(同样文本可能解析出 yes/no/true/false)
适合规模中小型配置数据交换复杂层次配置
学习曲线半小时上手几分钟看似简单实际坑多

经验法则机器之间传数据用 JSON;人写配置用 TOML;只有当你确实需要锚点、引用、复杂结构时才用 YAML。


13、各语言的 TOML 库

语言推荐库
Rust标准生态:tomlcrate
Python3.11+ 内置tomllib(只读);写入用tomli-wtomlkit
Gogithub.com/BurntSushi/tomlgithub.com/pelletier/go-toml/v2
Node.js / TypeScript@iarna/tomlsmol-toml
Javatomlj
C/C++tomlplusplus

完整列表见官方维护的清单:https://github.com/toml-lang/toml/wiki。

14、写在最后

TOML 的设计哲学可以浓缩成一句话:

最少的规则、最明确的类型、最不挑剔的人。

它不会取代 JSON 在数据交换里的位置,也不会取代 YAML 在 Kubernetes、Ansible 里的生态。但只要你在写"人会反复打开来手动改的配置文件",TOML 几乎都是更省心的那个选择。

下次新建config.json之前,不妨先想想:要不要换成config.toml

http://www.jsqmd.com/news/868898/

相关文章:

  • 别再让Simulink乱起名了!手把手教你配置Signal Properties,让生成C代码的变量名一目了然
  • FPGA视频流UDP传输实战:如何用QT上位机接收并显示1280x720@60Hz网络视频(附源码解析)
  • 大模型推理服务排队层归零:低延迟与确定性响应的工程实践
  • RTX5库版本中断优先级问题解析与解决方案
  • ESP32-S3玩转DHT11:手把手教你从零写驱动,避开微秒级时序的那些坑
  • SQLite环境配置踩坑实录:从下载dll文件到VS项目成功调用的完整避坑指南
  • 搜索题目:网格中的最短路径
  • 2026年靠谱的陕西莱姆石/莱姆石口碑好的厂家推荐 - 行业平台推荐
  • bx-et 算法
  • mysql 常用知识点总结
  • Spring Security OAuth高危漏洞修复指南:状态校验与JWT scope越权防护
  • UE5 GAS中FGameplayEffectContext的深度应用与定制
  • 探索Pandas groupby的各种技巧和应用实例
  • STM32F103用CubeMX测按键时长:从原理到代码,手把手教你实现高精度脉宽测量
  • 技术人创业失败复盘:我们烧完500万学到的教训
  • 基于Netty的TCP客户端实现与优化:封装断线重连、连接保持、处理线程池重连TCP之后获取Chanel失败问题
  • LVGL与GUI Guider嵌入式GUI开发实战:从环境搭建到性能优化
  • 运算放大器核心参数解析与电路设计实战指南
  • adb 常用指令
  • 微软转型:从Windows依赖到云与AI双引擎驱动的技术架构解耦
  • 鱼类检测 - 目标检测数据集(2026 新增草鱼 + 鲢鱼标注|VOC+YOLO 双格式)
  • SAP变式被锁死怎么办?手把手教你用RSVARENT程序绕过DB278权限错误
  • peerstream像素流多服务器部署(多流实现原理)
  • 硬件工程师的PSpice效率手册:如何快速为复杂封装器件(如7引脚MOS管)创建自定义仿真符号
  • 2026年评价高的特种线缆/电力线缆/新疆低压电力电缆/新疆电力电缆推荐品牌厂家 - 品牌宣传支持者
  • 昇腾CANN cann-samples:从示例代码到生产力工具的全路径
  • 年产2万吨山楂酒工厂的设计-发酵工段及车间的设计(lunwen+任务书+cad图纸)
  • Elm Native UI开发环境配置:完整的环境搭建与依赖管理教程
  • 3步解决AlphaFold 3输出文件格式兼容问题:MMCIF到PDB快速转换指南
  • 7步搞定MASA全家桶汉化包:让你的Minecraft模组说中文