【问题标题】:Python setuptools: Distribute configuration files to OS specific directoriesPython setuptools:将配置文件分发到操作系统特定的目录
【发布时间】:2016-10-22 14:10:02
【问题描述】:

我在 Python setuptools 中遇到了先有鸡还是先有蛋的问题。

我想要实现的是将配置文件与我的 pip 包(这本身完全可以使用setup.py 中的data_files 参数)分发到操作系统特定的用户配置文件的公共位置(例如@987654324 @ 在 Linux 上)。

我发现操作系统“特异性”可以使用appdirs[1] PyPi 包来解决。还有我的问题 - 安装我自己的包时不能保证安装appdirs,因为它是我的包的依赖项,因此安装在它之后(承诺的鸡肉或鸡蛋:))

我的setup.py 包含这样的内容:

from setuptools import setup
from appdirs import AppDirs
...
setup(
...
    data_files=[
        (AppDirs(name, author).user_config_dir, ['config/myconfig'])
    ],
...
)

不编写我自己的 setuptools 版本可以解决这个问题吗(暗示;))?

[1]:https://pypi.python.org/pypi/appdirs

【问题讨论】:

  • 不完全回答您的问题,但我的建议是使用data_files 分发您的文件的通用 副本,然后在您的应用程序首次运行时,与@987654330 联系@ 如果用户特定文件存在,如果不存在,则在第一次运行时通过复制分发的文件来创建它(您可以使用 pkg_resources 找到它)。
  • @shevron 这实际上是比我最初的想法更好的解决方案! :) 不幸的是,我正在为pkg_resources 苦苦挣扎。请您回答(最好用简短的 sn-p 怎么样),以便我可以将其标记为正确? ;)

标签: python setuptools setup.py


【解决方案1】:

正如我在评论中提到的,我建议将您的文件的通用副本与您的包一起分发,然后在运行时将其复制到用户的配置目录(如果它不存在)。

这应该不是很难,涉及到:

  1. 使用setuptoolspackage_data(而不是data_files)。这会将文件放置在运行时可使用pkg_resources 访问的位置,即特定操作系统的“正确”位置

  2. 程序运行时,使用appdirs 查找用户特定的本地安装文件。

  3. 如果不存在,使用pkg_resources查找文件,复制到appdirs提供的位置

虽然我还没有这样做,但由于pkg_resources 的工作方式,这个过程应该可以很好地适用于多个操作系统和环境,并且作为奖励,在开发过程中也是如此。

示例setup.py

在 setup.py 中,您应该确保使用 package_data 包含您的包的数据文件:

setup(
    # ...
    data_files={
        "my_package": [ "my_package.conf.dist" 
    }
    # ...
)

示例应用代码:

import os.path
import pkg_resources
import appdirs

def main():
    """Your app's main function"""
    config = get_config()
    # ... 
    # ...

def get_config():
    """Read configuration file and return its contents
    """
    cfg_dir = appdirs.user_config_dir('MyApplication')
    cfg_file = os.path.join(cfg_dir, 'my_application.conf')
    if not os.path.isfile(cfg_file):
        create_user_config(cfg_file)
    with open(cfg_file) as f:
        data = f.read()
        # ... probably parse the file contents here ...
        return data

def create_user_config(cfg_file):
    """Create the user's config file

    Note: you can replace the copying of file contents using shutil.copyfile
    """
    source = pkg_resources.resource_stream(__name__, 'my_package.conf.dist')
    with open(cfg_file, 'w') as dest:
        dest.writelines(source)

我希望这可以清除 pkg_resourcespackage_data 的用法。

【讨论】:

    猜你喜欢
    • 2013-11-18
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 2012-12-30
    • 2018-01-19
    • 2020-10-15
    • 2019-08-05
    • 1970-01-01
    相关资源
    最近更新 更多