python - 使用配置文件打包 python 应用程序?
问题描述
我正在编写一个 Python CLI 应用程序并想要打包它。我需要应用程序有一个适用于整个“安装”的配置文件(即无论用户从哪里调用我的 CLI 应用程序,它都需要读取此配置文件)。
如果可以避免的话,我希望它位于包安装目录中,而不仅仅是文件系统上的某个任意位置。这样做的简单方法是什么?
解决方案
很抱歉给出“这不是你想要做的”的答案,但我强烈建议不要将可编辑的配置文件捆绑到你的包中。原因是:
- 任何严肃的操作系统都有明确定义的标准,用户或系统级配置应该去。将您的应用程序的配置也放在那里一点也不杂乱。
- Python 包(读取、
.wheel
文件)不需要解压缩即可运行,因此任何支持 python 的操作系统都可能在安装时选择不这样做。如果要编辑其中的配置,则需要先解压缩包,这有点不方便。 - 出于同样的原因,无法使用搜索工具找到配置。如果您的用户忘记了它的位置,那么祝他们好运。
- 最后也是最不重要的,假设可执行文件是静态的。在编译代码的其他语言中,没有办法不编译,但对于解释性语言,我认为效仿是一种很好的风格。
但是遵循标准的最佳理由通常是您可以使用支持该标准的编写良好的工具,在这种情况下appdirs
。它可以(除其他外)为您找到通用的配置目录,因此使用它就像这样简单:
from pathlib import Path
from appdirs import site_config_dir
from configparser import ConfigParser
def load_config():
# .ini is easiest to work with, but .toml is probably better in the long run
cfg_loc = Path(site_config_dir(appname="my_cli_app", appauthor="K4KFH")) / "config.ini"
# that's it, that was the magic. the rest of the code here is just for illustration
if not cfg_loc.exists():
cfg_loc.parent.mkdir(parents=True, exist_ok=True)
with open(config_loc) as f:
f.write(
"[basic]\n"
"foo = 1\n"
)
print(f"Initialized new default config at {config_loc}.")
cfg = ConfigParser()
cfg.read(cfg_loc)
return cfg
在 Windows 上,这将为您提供:
>>> cfg = load_config()
Initialized new default config at C:\ProgramData\K4KFH\my_cli_app\config.ini.
>>> cfg["basic"]["foo"]
1
在 debian buster 上:
>>> cfg = load_config()
Initialized new default config at /etc/xdg/my_cli_app/config.ini.
>>> cfg["basic"]["foo"]
1
推荐阅读
- oop - 我如何正确(惯用地)在飞镖中做私人成员?
- javascript - 如何在 Puppeteer 中选择 iframe 元素中的元素
- python - 价值分配没有按我预期的方式工作
- php - 如何使用 JOIN 管理来自 3 个不同表的 SELECT 数据?
- mathematical-optimization - 问题不遵循 CVXPY 中的 DCP 规则
- python - 如果 slug 已经存在,则跳过保存行以避免 IntegrityError - Django
- java - 是否有任何方法或参数可以从条带 api 获取无效/停止卡信息我只从条带中获取到期月/年
- python - 为什么我的字符串中的变量没有与连接函数连接?
- angular - 创建一个新的 Angular 8 项目并没有给我选项
- amazon-web-services - AppSync 查询 sortField: "ceatedAt" 设置为降序