持续优化 8 年,这种自动化配置开始广受欢迎!
有 rust 语言的包管理工具 cargo;
类似于 docker 的容器工具 containerd;
go 语言很多项目都喜欢用。比如静态网站生成工具 Hugo、数据库 InfluxDB、GitLab CI。
python 项目也开始接纳。包管理工具 pip、pipenv 和 Poetry 都是用的 TOML,1现在连官方的 metadata 管理也开始支持 toml。
1. 一个小例子
为什么新项目这么喜欢 TOML 呢?让我们先来看一个 TOML 的小例子吧,看完了说不定你就知道了。
[project]
name = "spam"
version = "2020.0.0"
description = "Lovely Spam! Wonderful Spam!"
readme = "README.rst"
requires-python = ">=3.8"
license = {file = "LICENSE.txt"}
keywords = ["egg", "bacon", "sausage"]
字符串
注释
数字
布尔值
数组
哈希表
甚至连时间格式都支持
2. 字符串
name = "spam" #OK
name_1 = spam #错误
"name_2" = "spam" #OK
裸键只能包含 ASCII 字母,ASCII 数字,下划线和短横线(A-Za-z0-9_-
),引号键则可以支持特殊字符,甚至是空格。当键中包含特殊字符的时候,使用引号键。
'name@! erf:' = 'spam' # OK
name@! erf: = 'spam' # 错误
name = """
this is a
new line
command"""
this is a
new line
command
\
:name = """
this is a \
new line \
command"""
this is a new line command
3.数字
age1 = 18
age2 = -2
age3 = +16
age4 = 11.2
age1 = 0b11
age2 = 0o12
age3 = 0xb
{
'age1': 3,
'age2': 10,
'age3': 11
}
4. 布尔
bool1 = true
bool2 = false
5. 时间
时间类型是 toml 的一大特色,因为绝大多数的配置文件格式都是不支持时间类型的。toml 遵循的是 RFC 3339 时间格式,只要照着格式写,解析出来会自动转成编程语言的时间类型。
ts = 2021-01-06 07:30:00
ts1 = 2021-01-06 07:30:00.1234
time1 = 07:30:00
{
'ts': datetime.datetime(2021, 1, 6, 7, 30),
'ts1': datetime.datetime(2021, 1, 6, 7, 30, 0, 123000),
'time1': datetime.time(7, 30)
}
6. 数组
users = [
['iswy', '男'],
['you', '女'],
]
{
'users': [
['iswy', '男'],
['you', '女']
]
}
7. 哈希表
user = {name='iswy', gender='男'}
{
'user': {
'gender': '男',
'name': 'iswy'
}
}
这种写在 key 后面的表叫内联表。还有一种用法,类似于 ini 格式中的 section,用于分组管理,暂且把它叫做外联表。比如上面的例子,可以换一种形式,得到的结果是完全一样的。
[user]
gender = '男'
name = 'iswy'
[user]
cat = ['admin', 'normal']
[user.student]
name='iswy'
age=19
[user.teacher]
name='you'
age=32
如果你觉得这种风格你不喜欢,也可以换成下面的风格:
[user]
cat = ['admin', 'normal']
# student
student.name='iswy'
student.age=19
# teacher
teacher.name='you'
teacher.age=328
site.'x.com' = 'http://x.com'
我个人更倾向于子表嵌套的风格,因为这样的表述看起来更加简洁。
表和数组的配套使用
最后我们要考虑的问题是当有多个用户需要配置,我们要使用表数组进行分组呢?
[[user]]
[user.student]
name='iswy'
age=19
[user.teacher]
name='you'
age=328
[[user]]
[user.student]
name='iswy2'
age=192
[user.teacher]
name='you2'
age=3282
得到的结果:
{
'user': [
{
'student': {'age': 19, 'name': 'iswy'},
'teacher': {'age': 328, 'name': 'you'}
},
{
'student': {'age': 192, 'name': 'iswy2'},
'teacher': {'age': 3282, 'name': 'you2'}
}
]
}
使用 python 语言解析 toml :
import toml
with open('api.toml', encoding='utf-8') as f:
data = toml.loads(f.read())