前言
开发项目时,为了维护一些经常需要变更的数据,比如数据库的连接信息、请求的url、测试数据等,往往会将这些数据写入配置文件,将数据和代码分离。这样做的好处是只需要修改配置文件的参数,就可以快速完成环境的切换或者测试数据的更新。
这个固定文件我们可以直接写成一个 .py 文件,例如 settings.py 或 config.py,这样的好处就是能够在同一工程下直接通过 import 来导入当中的部分。但如果我们需要在其他非 Python 的平台进行配置文件共享时,写成单个 .py 就不是一个很好的选择。
那么,这时我们就应该选择通用的配置文件类型来作为存储这些固定的部分。目前常用且流行的配置文件格式类型主要有 ini、json、toml、yaml、xml 等,这些类型的配置文件我们都可以通过标准库或第三方库来进行解析。
配置文件及解析方式
INI
INI 格式,ini 即 Initialize 初始化之意,最初只在 Windows 上流行,之后成为配置标准格式。ini 文件的写法通俗易懂,往往比较简单,通常由节(Section)、键(key)和值(value)组成。
[localdb]
host = 127.0.0.1
user = root
password = 123456
port = 3306
database = mysql
Python 本身内置的 configparser 标准库,我们直接就可以用来对 ini 文件进行解析。如我们将上述内容保存在一个名为 db.ini 的文件中,然后使用 read() 方法来进行解析和读取,最后通过 items() 方法来获取指定节点下的所有键值对:
>>> from configparser import ConfigParser
>>> cfg = ConfigParser()
>>> cfg.read("/Users/Bobot/db.ini")
['/Users/Bobot/db.ini']
>>> cfg.items("localdb")
[('host', '127.0.0.1'), ('user', 'root'), ('password', '123456'), ('port', '3306'), ('database', 'mysql')]
configparser 默认将值以字符串的形式呈现,获取到键值对后,将其转换成字典,通过解包的方式进行参数传递,保持代码简洁:
#!pip install pymysql
import pymysql
from configparser import ConfigParser
cfg = ConfigParser()
cfg.read("/Users/Bobot/db.ini")
db_cfg = dict(cfg.items("localdb"))
con = pymysql.connect(**db_cfg)
JSON
JSON(JavaScript Object Notation)是一种类似于 JavaScript 的格式,是目前在互联网较为流行的一种数据交换格式。
{
"localdb":{
"host": "127.0.0.1",
"user": "root",
"password": "123456",
"port": 3306,
"database": "mysql"
}
}
json 库读取 json 文件相对简单容易,而且很容易解析成 Python 的字典对象。如我们将上述内容保存在一个名为 db.json的文件中:
>>> import json
>>> from pprint import pprint
>>>
>>> with open('/Users/Bobot/db.json') as j:
... cfg = json.load(j)['localdb']
...
>>> pprint(cfg)
{'database': 'mysql',
'host': '127.0.0.1',
'password': '123456',
'port': 3306,
'user': 'root'}
YAML
YAML(Yet Another Markup Language)是 JSON 的扩展,旨在更易于手动编写。
config.yaml:
mysql:
host: "127.0.0.1"
port: 3306
user: "root"
password: "123456"
database: "test"
parameter:
pool_size: 5
charset: "utf8"
fields:
pandas_cols:
- id
- name
- age
- date
读取方式:
>>> import os
>>> from pprint import pprint
>>>
>>> with open(os.path.expanduser("~/config.yaml"), "r") as config:
... cfg = yaml.safe_load(config)
...
>>> pprint(cfg)
{'mysql': {'database': 'test',
'fields': {'pandas_cols': ['id', 'name', 'age', 'date']},
'host': '127.0.0.1',
'parameter': {'charset': 'utf8', 'pool_size': 5},
'password': '123456',
'port': 3306,
'user': 'root'}}
TOML
TOML(Tom's Own Markup Language)旨在成为 YAML 的轻量级替代品。其规范比较短,已经在一些地方流行了(比如 Rust 的包管理器 Cargo 就用它来进行包配置)。
config.toml:
[mysql]
host = "127.0.0.1"
user = "root"
port = 3306
database = "test"
[mysql.parameters]
pool_size = 5
charset = "utf8"
[mysql.fields]
pandas_cols = [ "id", "name", "age", "date"]
读取方式:
>>> import toml
>>> import os
>>> from pprint import pprint
>>> cfg = toml.load(os.path.expanduser("~/Desktop/config.toml"))
>>> pprint(cfg)
{'mysql': {'database': 'test',
'fields': {'pandas_cols': ['id', 'name', 'age', 'date']},
'host': '127.0.0.1',
'parameters': {'charset': 'utf8', 'pool_size': 5},
'port': 3306,
'user': 'root'}}
总结
本文列举了一些主流且常见的配置文件类型及其 Python 的读取方法,除了这些主流的配置文件类型之外,像一些 .cfg、.properties 等都可以作为配置文件。
这些配置文件之间各有优劣,可以根据自己实际的需求和团队协作要求来具体选择。
选择配置格式是一种微妙的权衡。但是,一旦你做出决定,Python 就可以使用少量代码来解析大多数流行的格式。