每个python项目几乎都会有一个配置文件,会把一些配置性的常量放到配置文件中,对一些比较初级的开发者,经常会犯以下的一些问题:
- 配置文件命名很随意,一会是config,一会是setting,一会是settings等;
- 配置文件里的变量命名很随意,一会大写,一会小写,一会驼峰,一会又下划线;
- 对配置文件的本质没理解,直接把配置文件就提交到代码库里。
这三个问题很普遍,既然是python,按我们就应该按python的约定,配置文件名就是settings,变量名应该都是下划线风格,配置文件中的应该都是常量,因此应该都是大写等,这些都是命名规范。
配置文件,为什么被叫配置文件,是因为这些变量可能会易变的,可能会根据不同的部署环境而变化,因此它不应该直接提交到代码库里,提交到代码库里的应该是一个示例文件settings-example.py,需要使用的时候,应该先将这个文件复制到settings.py文件中,该文件应该在.gitignore文件中进行排除,避免被误提交到代码中。
上面这些都是常见的问题,这也是常见的解决方式,但是关于配置文件还有一个问题以前是考虑不够的。如果配置文件中的变量比较多,而且不停迭代部署版本的时候,就会有比较大的问题,经常得仔细比较哪些变量做了更新,哪些变量要复制到settings.py文件中,很容易搞错,而且这种错误可能并不容易被发现。
今天改以前同事的遗留代码时,花了不少时间去整理配置文件,完善了这个配置文件的实践。提交到代码库中的配置文件有两个:
- settings_base.py: 基础配置文件,就是完整的配置文件,所有配置变量都在这个文件里;
- settings-example.py: 示例配置文件,这个文件可以理解为继承自settings_base.py,把需要改变的配置文件放到这个文件中,实际部署的时候,把这个文件复制到settings.py,然后修改其中的值,如果有其他的配置变量需要修改,则也可以加到这里,但是对应的配置变量必须是在settings_base.py中有定义的。在其他地方不会直接引用settings_base.py中的常量,而只是引用settings.py。
看一下settings-example.py文件的主要代码,就比较清楚了:
代码语言:javascript复制# 引入所有的基础配置文件中的配置变量
from settings_base import *
# 缓存基础配置文件中的变量名
__local_keys__ = set(locals().keys())
# ------------------------------------------------------------------------------------
# --------- 注意这里的配置应该都是在 settings_base.py 中存在的, 否则启动会报错 -----------
# ------------------------------------------------------------------------------------
# 是否为测试模式
DEBUG = False
# 是否开启在线接口文档
# 生产环境上,通常需要关闭
OPEN_DOCS = False
# 更多的配置变量......
# 校验是否配置异常,避免配置过程中不慎搞错了变量名
__new_locals__ = set(locals().keys())
__new_locals__.remove('__local_keys__')
if len(__new_locals__) != len(__local_keys__):
__keys = __new_locals__.difference(__local_keys__)
raise Exception(f'{", ".join(__keys)}: 这些配置变量不在基础配置文件 settings_base.py 中')
这里通常只需要存储哪些和基础配置文件中不一样的即可,通过locals()函数实现配置变量检验,避免配置过程中不慎搞错了变量名。