python - 如何记录配置文件?
问题描述
配置文件文档是否有任何最佳实践,尤其是对于 python?
特别是在科学计算中,通常使用配置文件作为输入来控制批处理作业(例如模拟),并期望用户为他们的场景定制大部分配置。(配置也可能在不同的处理模块中进行选择,每个模块拥有不同的配置字段套件。)因此,用户应该知道:每个设置的含义或效果;哪些设置未使用(在哪些情况下);什么是默认值(以及允许的值或范围);等等
我发现不完整的配置文件文档很常见。根本问题似乎是,如果文档与代码分开维护,它们就会变得不同步。(这对于 API 文档来说似乎不太成问题,因为标准做法涉及并置文档字符串和从函数签名/argspec 自动生成。)例如,如果使用标准 python configparser 一次来解析配置文件,那么访问单个属性的代码(并隐式确定配置模式)可能仍然分布在整个代码库中(并且可能仅在运行时可用,而不是在构建文档时可用)。
进一步的想法:
- 用用户自定义的 python 脚本(只需要 API 文档)替换配置文件(yaml 或类似文件)是不好的做法吗?
- 分发一个注释良好的示例配置文件(也用于自动测试):如果不同的场景重复大部分但需要一些完全不同的字段,如何维护?
- 是否可以维护一个模式,既可以在代码中使用(帮助解析、验证和设置默认值),也可以以某种方式生成文档?
- 是否有一种人类可读/可写的方式来(反)序列化代表新批处理过程的某些(子)类实例的状态(以便现有文档涵盖配置)?
解决方案
就个人而言,我喜欢使用该argparse
模块进行配置,并从环境变量中读取每个设置的默认值。这将设置和文档集中在一个地方,并允许用户在命令行上调整设置或在环境变量中设置并忘记它们。不过,在命令行上输入密码时要小心,因为其他用户可能会在进程列表中看到您的命令行参数。
这是一个使用环境变量的示例:argparse
def parse_args(argv=None):
parser = ArgumentParser(description='Watch the raw data folder for new runs.',
formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument(
'--kive_server',
default=os.environ.get('MICALL_KIVE_SERVER', 'http://localhost:8000'),
help='server to send runs to')
parser.add_argument(
'--kive_user',
default=os.environ.get('MICALL_KIVE_USER', 'kive'),
help='user name for Kive server')
parser.add_argument(
'--kive_password',
default=SUPPRESS,
help='password for Kive server (default not shown)')
args = parser.parse_args(argv)
if not hasattr(args, 'kive_password'):
args.kive_password = os.environ.get('MICALL_KIVE_PASSWORD', 'kive')
return args
设置这些环境变量可能有点混乱,尤其是对于系统服务。如果您使用的是 systemd,请查看service unit,并小心使用,EnvironmentFile
而不是Environment
任何秘密。Environment
任何用户都可以使用systemctl show
.
我通常使默认值对在他们的工作站上运行的开发人员有用,因此他们可以在不更改任何配置的情况下开始开发。
另一种选择是将配置设置放在一个settings.py
文件中,并注意不要将该文件提交给源代码管理。我经常提交settings_template.py
用户可以复制的文件。
如果您的设置非常复杂/灵活以至于环境变量或设置文件变得混乱,那么我会将项目转换为带有 API 的库。然后用户编写一个调用您的 API 的脚本,而不是设置。您也不必费力在 PyPI 上托管您的库。pip
例如,可以从GitHub 存储库安装。
推荐阅读
- ios - Flutter:升级到 Flutter facebook login v3.00 后运行 pod install 时出错
- excel - 确定以上单元格的值在VBA for Excel中相同后如何添加一行
- python - 如何从字典的输出中删除括号
- python - 如何找到两个元组之间的共同元素
- python - python - 如何将csv文件中的列转换为python中的数组,第一个值是数组变量名?
- aws-cdk - 是否可以创建自定义 cdk init 模板以将 pipenv 用于我的 python 项目?
- c - 警告:格式“%d”需要“int *”类型的参数,但参数 3 的类型为“uint8_t * {aka unsigned char *}
- python - Python:NameError:未定义全局名称“nt”
- python - Python open3D没有属性'create_coordinate_frame'
- java - Vector中的对象无法转换为int