【问题标题】:Python Packaging: user specified file pathPython打包:用户指定的文件路径
【发布时间】:2021-08-19 23:01:28
【问题描述】:

我正在编写一个依赖于许多大型数据文件的 python 包。这些文件包含在软件包中。相反,用户需要将这些文件保存在磁盘上(使用任意路径)。让我的包知道这些文件的位置的最佳方法是什么?

我一直在阅读有关 setup.pysetup.cfg 的信息,但我仍然不知道该怎么做。在我看来,setup.cfg 中的用户可编辑选项将是一个不错的选择,但我不知道是否可以,是否可以完成,或者如果可以,我会怎么做......

我确实看到了这个几乎相同的问题,Python Packaging: Ask user for variable values when (pip) installing,它侧重于 pip 期间的用户输入(这在 cmets 中是不鼓励的)。 如果这确实是一个很好的解决方案,我也对如何做到这一点感兴趣。

在我私下开发的包中,我使用了模块常量,如

DEFAULT_PATH_FILE1 = "my/path/to/file1.csv"
DEFAULT_PATH_FILE2 = "my/path/to/file2.csv"

等等。以及使用这些常量初始化的属性。这似乎根本不适合分发。

【问题讨论】:

  • 对上下文很重要,你的包是否提供命令行界面?
  • 不,这不是本意。它(主要)定义了一个便于跨不同数据文件进行数据分析的类。预期用途是随意导入和使用这个类。

标签: python python-packaging


【解决方案1】:

您想要的不是安装期间的一次性设置(现代.whl 安装也是不可能的),而是客户端在运行时随时配置库的一种方式。鉴于您不提供 cli,您可以使用环境变量作为提供该选项的选项,或者查找用户定义的配置文件。

这是一个使用appdirs 找出配置文件所在位置的简单方法。它在导入包时加载,并告诉客户如果配置文件不存在有多糟糕。通常是:

  • 写日志消息
  • 使用默认设置
  • 抛出某种异常
  • 以上的组合
from logging import getLogger
from pathlib import Path
from configparser import ConfigParser
# loads .ini format files easily, just to have an example to go with

import appdirs  # needs to be pip-installed

log = getLogger(__name__)
config = ConfigParser(interpolation=None)


# load config, substitute "my_package" with the actual name of your package
config_path = Path(appdirs.user_config_dir("my_package")) / "user.ini"
try:
    with open(config_path) as f:
        config.read_file(f, source="user")
except FileNotFoundError:
    # only do whatever makes sense
    log.info(f"User config expected at '{config_path}', but not found.")
    config.read_string("[pathes]\nfile_foo=foo\nfile_bar=bar")  # dubious
    raise ImportError(f"Can't use this module; create a config at '{config_path}'.")


class Foo:
    def __init__(self):
        with open(cfg["pathes"]["file_foo"]) as f:
            self.data = f.read()

【讨论】:

  • 除非在导入模块之前配置了日志系统,否则该日志事件不会去任何地方。
  • True、shortlongerlongest 解释了如何设置记录器,以防万一有人感兴趣。问题与日志无关,所以我会在评论中留下它。
【解决方案2】:

这听起来像运行时配置。这与setup.py 无关,它与安装你的包有关。

对于应用程序配置,通常通过命令行参数、环境变量或配置文件指定此资源位置。您通常需要硬编码一些合理的默认路径以防用户未指定任何配置,或者在资源不存在/未找到的情况下引发异常。

环境变量示例:

import os

DEFAULT_PATH_FILE1 = "/default/path/to/file1.csv"
PATH_FILE1 = os.environ.get("PATH_FILE1", DEFAULT_PATH_FILE1)

【讨论】:

  • 没错,是运行时配置。该包将主要作为一个模块加载——还有没有办法让一次性命令行配置命令来指定路径?配置文件听起来很吸引我。这是怎么做到的?
  • 您只需从~/.config/myapp.conf 或任何地方的文件加载配置。记录默认配置文件路径并提供覆盖此位置的方法(例如,另一个环境变量MYAPP_CONF_FILE)。配置文件的存在通常应该是可选的
猜你喜欢
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
  • 2012-12-13
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 2014-09-12
相关资源
最近更新 更多