【问题标题】:setup.py in python: how to install subpackages?python中的setup.py:如何安装子包?
【发布时间】:2025-11-22 19:45:01
【问题描述】:

考虑以下包结构:

src/
   /__init__.py
   bar.py
   /foo
       /__init__.py
       foobar.py

我想写一个 setup.py 如果我这样做:

pip install -e .

从根目录开始,以下所有操作都可以:

import src
import src.foo
import foo

我可以使用例如轻松实现前两个。 find_namespace_packages,但我尝试了 find_namespace_packages()、find_packages()、package_dir 的各种组合,也能够在不指定前缀(即 src.foo)的情况下导入子包 foo 而没有成功。我该怎么做?

【问题讨论】:

  • 我很确定你不能用你构建/打包代码的方式。 Python 将在src 中查找,每个__init__.py 都允许对其进行索引,因此它被视为同一包的一部分。此外,还有潜在的命名空间冲突。如果你有csv 而不是foo 怎么办?这会破坏 python 的默认 csv 库。通过指定src.foo,可以明确定义foo 的位置。
  • 您真正应该考虑的是将foo 作为 PyPI 包的单独存储库,然后将其添加到您的 requirements.txt 中,然后在 src/__init__.py 中添加 import foo。然后src.foo 将可用。
  • @astrochun 我明白你的意思。只是我正在处理一个代码库,其中有一堆带有模块的子包,它们有时使用 src.foo 导入,有时只使用 foo。我认为这是因为代码是通过在 pythonpath 上进行黑客攻击开发的,因此所有子模块都可以访问。
  • 啊,我建议重构它以保持一致性,因为您希望将它打包在一起。这样使用src.foofrom .. import foo 之类的东西是一致的。当这些代码增长时,现在就这样做会为您省去头疼的问题。我在下面提供了一个关于如何分离事物的答案。

标签: python setup.py


【解决方案1】:

也许我错了,但我相当肯定你不能用你构建/打包你的 repo 的方式。 Python 将在src 中查找,每个__init__.py 都允许对其进行索引,因此它被视为同一包的一部分。此外,还有潜在的命名空间冲突。如果你有csv 而不是foo 怎么办?这会破坏 python 的默认 csv 库。通过指定 src.foo,可以明确定义 foo 的位置。

我能想到的唯一方法是将您的代码放在两个单独的存储库中,并在 PyPI 上使用foo(即pip install foo)。将其添加到您的requirements.txt 之后,您可以执行以下操作:

import foo

src/__init__.py。这将允许您拥有:src.foofoo

【讨论】: