【问题标题】:Packaging a python app with a config file?使用配置文件打包 python 应用程序?
【发布时间】:2021-06-20 07:31:58
【问题描述】:

我正在编写一个 Python CLI 应用程序并希望将其打包。我需要应用程序有一个适用于整个“安装”的配置文件(即无论用户从哪里调用我的 CLI 应用程序,它都需要读取此配置文件)。

如果我可以避免的话,我希望它位于包安装目录中,而不仅仅是文件系统上的某个任意位置。这样做的简单方法是什么?

【问题讨论】:

  • 要很好地理解您的问题:它是仅用于 安装 的配置文件(您已将该词放在引号中),还是应该在每次使用时使用的配置文件执行您的应用程序?在哪个平台上?
  • 对不起,我的意思是它是一个配置文件,应该在应用程序的每次执行时使用。在 Linux (Debian/Ubuntu) 上。我主要想区分一种系统范围的配置文件(我想要的)和每个用户的配置文件。
  • 非常好的问题。可以肯定的是,配置应该是可编辑的,对吧?
  • 我以两种不同的方式做了类似的事情。选项 1 是传入 config.ini 文件的路径。另一个是读取默认值并能够使用 CLI 参数来覆盖单个值。
  • 我的应用程序中通常有 4 个级别的配置。 1) 默认值,它是一个 .ini 文件,它是包的一部分,2) user.ini,(或 site.ini,在这种情况下),它使用 default.ini 初始化,然后可以通过以下方式更改用户,3) 遵循模式 MY_CLI_APP_BASIC_FOO=1 的环境变量,以模仿我帖子中的设置,以及 4) 调用应用程序时的选项,例如 $ my-cli-app --basic-foo 1 sub-command

标签: python python-packaging


【解决方案1】:

很抱歉给出“这不是您想要做的”的答案,但我强烈建议您不要将可编辑的配置文件捆绑到您的包中。原因是:

  • 任何严肃的操作系统都有明确定义的标准,用户或系统级配置应该去哪里。将应用的配置也放在那里一点也不麻烦。
  • 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

【讨论】:

  • 但是cfg_loc 没有定义。 cfg_dir 被定义了,这令人困惑,因为它是一个文件而不是一个目录。也许将cfg_dir 传递给load_config,这样您就可以使用每个用户的配置。
  • @astrochun 早期版本的错字,我的错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-27
  • 1970-01-01
  • 2011-12-10
  • 2012-07-13
  • 2021-05-05
  • 1970-01-01
相关资源
最近更新 更多