配置文件,首选 YAML 和 TOML

1. 配置文件是什么?

配置文件是用于配置计算机程序的参数和初始化设置的文件。如果没有这些配置,程序可能无法执行。

比如现在你要开发一款 app, 当部署这款 app 时,你需要配置它的 host 地址、数据库地址、数据库名称,这些都可以作为配置项写入配置文件。当项目上线,需要换一个环境运行时,只需要修改配置文件,不需要去代码当中到处查找。

配置文件通常是 key/value 的形式存在,任何支持解析 key/value 形式的文件都是可以作为配置文件的。

现在主流的配置文件格式非常多,比如:

  • Linux 系统中的 .bashrc
  • YAML
  • TOML
  • JSON
  • XML
  • INI

这些都是常用的配置文件格式。接下来,我们来看看用得最多的几种配置文件怎么编写,又是如何通过 python 语言解析的。

2. yaml

# default
host: "http://www.iswy.com"
# 数据库
db:
  host: "http://www.iswydb.com"
  port: 3306
  name: "py"
# 账号
users:
  -
    name: "iswy"
    password: "123456"
  -
    name: "iswy_wang"
    password: "666666"

YAML 是目前最推荐的配置文件格式。优秀的配置文件标准它几乎都有:

  • 容易阅读和修改,支持注释。
  • 支持丰富的数据类型。
  • 不同格式的明确表达。

yaml 使用时需要注意:

  1. yaml 强制缩进。虽然不规定具体缩进几个空格,但是同一级的内容要保持相同的缩进。
  2. 冒号后面一定要加空格, 否则无法解析。

python 解析 yaml 可以使用 pyyaml 库,操作和标准的文件操作非常类似:

import yaml

with open('api.yml', encoding='utf-8') as f:
    data = yaml.load(f, Loader=yaml.SafeLoader)

得到的 data 就是解析后的数据,在 python 当中,它是一个嵌套的字典:

{
    'db': {
        'host': 'http://www.iswydb.com', 
        'name': 'py', 'port': 3306
    },
    'host': 'http://www.iswy.com',
    'users': [
        {'name': 'iswy', 'password': '123456'},
        {'name': 'iswy_a', 'password': '666666'}
    ]
}

想获取某一项配置,再通过字典的操作获取:

db_host = data['db']['host']

3. ini

[default]
host=http://www.iswy.com
[db]
host="http://www.iswydb.com"
port=3306
name="py"

ini 格式是用得非常多的配置文件格式,有大量的项目都使用 ini 编写配置文件,它比较适合配置项的数据类型只是简单的字符串、数字的情况,如果涉及数组和 key/value 的嵌套,会比较吃力。

ini 格式有几个概念需要了解。用 [] 的叫做 section, 用来对配置项进行分组, 下面的 port 和 name 叫做 option。 如果想获取某一个 option,必须先要获取 section。

通过 python解析 ini:

from configparser import ConfigParser

parser = ConfigParser()
parser.read("api.ini", encoding="utf-8")

host = parser.get("default", "host")
db_host = parser.get("db", "host")

ini 配置格式有几个注意点:

  1. section 无法嵌套, 嵌套后的效果和没有嵌套是一样的。
[default]
    [db]
    host=http://www.iswydb.com

获取这个 host 的方式不会发生任何变化,default 并不是 db 的父级。

  1. 字符串的表示不要加引号,否则引号也会被解析出来。
[db]
host = "http://www.iswydb.com"
host2 = http://www.iswydb.com

得到的结果:

"http://www.iswydb.com"
http://www.iswydb.com
  1. = 可以用空格,也可以不用。

4. json

{
  "db": {
    "host": "http://www.db.com",
    "port": 3306
  },
  "host": "http://www.iswy.com"
}

json 在配置文件中的使用频率是上面提到的格式中最低的,原因有几个:

  1. 不支持注释,
  2. 花括号太多,影响可读性。

通过 python 解析 json 文件:

import json

with open('api.json', encoding='utf-8') as f:
    data = json.loads(f.read())

5. toml

host = 'http://www.iswy.com'

# 数据库
[db]
host = "http://www.iswydb.com"
port = 3306
name = "py"

# 账号
users = [
    {name = 'iswy', password = '123456'},
    {name = 'iswy', password = '666666'}
]

TOML 结合了 ini 和 yaml 的优点:

  1. TOML 的写法和 ini 几乎一致,切换成本为 0 ;
  2. 支持所有的 YAML 数据类型,甚至支持时间格式;
  3. 支持像 ini 的 section 分组,只是在 TOML 中,它叫做 table;
  4. 解析像 YAML 那样简单。

在 python 中解析 TOML 先安装:

pip install toml

操作和普通文件的方式非常相似:

import toml

with open('api.toml', encoding='utf-8') as f:
    data = toml.loads(f.read())

TOML 的写法非常灵活,后面再出教程。

6. 什么样的数据适合放在配置文件里

配置文件的作用主要是给即将运行的程序提供初始值,凡是在环境发生改变时需要修改的选项就可以设置成配置项。比如上面的域名 host 和数据库设置。 当需要把程序部署到另外的环境,域名和数据库都有可能发生变化,此时可以设置成配置项。

什么样的数据不适合放在配置文件呢? 每次运行程序都需要检查的,最好不要放在配置文件中,而是通过编程语言进行设置,比如某个依赖文件的路径。

7. 什么要的配置文件格式是好格式

  • 容易阅读和修改、最好支持注释。 所以 json 不是一种好的格式。
  • 易于解析,支持多数据类型。 INI 和 xml 不合适。
  • 不同格式用不同的表达。 YAML 和 TOML 做得非常好。

用配置文件,选 YAML 和 TOML。

参考文献

  • https://jhall.io/posts/best-config-file-formats/