【问题标题】:Include a directory with setuptools installation在 setuptools 安装中包含一个目录
【发布时间】:2025-11-30 17:10:02
【问题描述】:

我制作了一个基于插件的程序,它从不同的目录加载插件,其中一个是模块所在的目录(为了方便在源存储库中运行以进行测试)。

我希望源存储库中当前的插件与模块一起安装,以便在任何安装时默认加载它们。这最好存储在 setup() 创建的鸡蛋中。

目前源码仓库的重要部分如下:

/path/to/repo/
    plugins/
        example.py
    myprog.py # the module
    myprog    # the script
    setup.py

setup.py 看起来像这样:

from setuptools import setup

setup(
    name = 'myprog',
    version = '1.0',
    scripts = ['myprog'],
    py_modules = ['myprog'],

    package_data = {
        '': ['plugins/']
    }
)

但是,plugins 目录不以任何方式包含在安装中。

我怎样才能包含它,以便该行

os.path.join(os.path.dirname(os.path.realpath(__file__)), 'plugins')

运行python3 setup.py install后会正确找到该目录吗?

【问题讨论】:

  • 将此路径sys.path.append(os.getcwd()+'/plugins') 添加到myprog.py 或者在哪里可以调用?
  • 不要定义静态路径!
  • 添加静态路径无法解决问题。我希望在安装中包含一个文件。更改程序以查看其原始位置不是有效的解决方案。

标签: python python-3.x packaging setuptools setup.py


【解决方案1】:

您的设置会通过创建一个每个人都可以导入的全局plugins 模块来破坏事情,或者每个人都会错误地导入。不要那样做。相反,请这样做:

  • 将您的myprog.py 文件打包。最简单的方法:mkdir myprog; mv myprog.py myprog/__init__.py
  • 然后,您可以将插件移动到子包中。 touch plugins/__init__.py; mv plugins myprog/
  • 使用子包,您根本不必使用包数据。
  • 要访问您的插件,只需对名为 foo.py 的插件执行 import myprog.plugins.foo
  • 另外:不要碰__file__,改用pkg_resources
  • 奖励积分:use entry points 用于您的脚本。

【讨论】:

  • 如果该目录中的文件不一定是源文件,例如语言包或图像怎么办?我如何保证该目录将被包含在内,并且模块将能够在安装后使用相对路径查看这些文件?
  • @2mac:此时,您可以使用package_data={'myprog': ['plugins/*'}。确保将您的文件添加到MANIFEST.in(该名称的谷歌)。我认为include_package_data 也可能有用。 (另外,您需要将py_modules = ['myprog'] 替换为packages = ['myprog', 'myprog.plugins'] 或使用setuptools 中的find_packages() 函数。
  • 这些会包含在安装中吗?根据文档,package_dataMANIFEST.in 仅声明要包含在源代码分发中的内容。这些需要与模块一起安装,以便可以作为数据文件访问。
  • @2mac: MANIFEST.in 声明源分发中的文件,package_data 安装它们。