我意识到这个问题之前就被问过(在 Python 中使用设置文件的最佳实践是什么?),但鉴于这是 7 年前提出的问题,我觉得随着技术的发展,再次讨论是有效的。
我有一个Python项目,需要根据环境变量的值使用不同的配置。由于使用环境变量来选择配置文件很简单,我的问题如下:
当根据环境需要多种配置时,什么格式被认为是软件行业中在 python 中设置配置文件的最佳实践?
我意识到 python 附带了一个 ConfigParser 模块,但我想知道使用 YAML 或 JSON 等格式是否会更好,因为它们易于跨语言使用,因此越来越受欢迎。当您有多种配置时,哪种格式更容易维护?
这确实是迟到了,但这就是我使用的并且我对它很满意(如果你愿意接受纯Python解决方案)。我喜欢它,因为我的配置可以根据使用环境变量的部署位置自动设置。我使用它的时间不长,所以如果有人发现问题,我会洗耳恭听。
结构:
|--settings
|--__init__.py
|--config.py
配置.py
class Common(object):
XYZ_API_KEY = 'AJSKDF234328942FJKDJ32'
XYZ_API_SECRET = 'KDJFKJ234df234fFW3424@#ewrFEWF'
class Local(Common):
DB_URI = 'local/db/uri'
DEBUG = True
class Production(Common):
DB_URI = 'remote/db/uri'
DEBUG = False
class Staging(Production):
DEBUG = True
__init__.py
from settings.config import Local, Production, Staging
import os
config_space = os.getenv('CONFIG_SPACE', None)
if config_space:
if config_space == 'LOCAL':
auto_config = Local
elif config_space == 'STAGING':
auto_config = Staging
elif config_space == 'PRODUCTION':
auto_config = Production
else:
auto_config = None
raise EnvironmentError(f'CONFIG_SPACE is unexpected value: {config_space}')
else:
raise EnvironmentError('CONFIG_SPACE environment variable is not set!')
如果我的环境变量设置在我的应用程序所在的每个位置,我可以根据需要将其带入我的模块中:
from settings import auto_config as cfg
如果你确实想使用基于环境的 YAML 配置,你可以这样做:
import yaml
import os
config = None
filename = os.getenv('env', 'default').lower()
script_dir = os.path.dirname(__file__)
abs_file_path = os.path.join(script_dir, filename)
with open(abs_file_path, 'r') as stream:
try:
config = yaml.load(stream)
except yaml.YAMLError as exc:
print(exc)
我认为查看 Python Django 设置模块的标准配置就是一个很好的例子,因为 Python Django Web 框架在商业项目中非常流行,因此代表了软件行业。
它对 JSON 或 YAML 配置文件不太感兴趣 - 它只是使用一个名为 settings.py 的 python 模块,可以将其导入到需要访问设置的任何其他模块中。那里还定义了基于环境变量的设置。以下是 Github 上 Django 的示例 settings.py 文件的链接:
https://github.com/deis/example-python-django/blob/master/helloworld/settings.py
这实际上取决于您的要求,而不是格式的流行程度。例如,如果您只需要简单的键值对,INI 文件就足够了。一旦您需要复杂的结构(例如数组或字典),我就会选择 JSON 或 YAML。 JSON 只是存储数据(它更适合系统之间的自动化数据流),而 YAML 更适合人类生成(或维护或读取)的文件,因为它有注释,您可以在文件中的其他位置引用值......并且最重要的是,如果您想要稳健性、灵活性以及检查文件结构正确性的方法(但不太关心数据的手动版本),我会选择 XML。
我建议尝试一下 trapdoor 进行交钥匙配置(免责声明:我是 trapdoor 的作者)。
我还喜欢利用这样一个事实,即您不必编译 Python 源代码并使用纯 Python 文件进行配置。但在现实世界中,您可能有多个环境,每个环境都需要不同的配置,并且您可能还想从环境变量或不在源代码控制中的文件中读取一些(主要是敏感的)信息(以防止错误地提交这些信息)。
这就是我编写这个库的原因:https://github.com/davidohana/kofiko, 它允许您使用纯 Python 文件进行配置,但也可以覆盖 .ini 或 env-vars 中的配置设置,并且还支持针对不同环境的自定义。
有关它的博客文章:https://medium.com/swlh/code-first-configuration-approach-for-python-f975469433b9
公共类(对象): XYZ_API_KEY = 'AJSKDF234328942FJKDJ32' XYZ_API_SECRET = 'KDJFKJ234df234fFW3424@#ewrFEWF'
本地类(通用): DB_URI = '本地/db/uri' 调试=真
类制作(普通): DB_URI = '远程/db/uri' 调试=假
班级舞台(制作): 调试=真