python个不同项目的库怎么能在同一个包里呢?

How can python libraries of different projects be in the same package?

假设您有一个名为 Ninja 的大型 (python) 软件项目。该项目有几个部分,如 serverclient,还有一个公共基础设施库,其中包含公共 类 和工具。当然,我会创建这样的包结构:ninja.coreninja.serverninja.client,其中 serverclient 以某种方式导入 ninja.core。出于开发目的(我们将 eclipse 与 Subversion 结合使用),coreserverclient 维护在不同的位置项目,从而导致这样的文件夹结构:

eclipse_workspace
|
>-Ninja_core
| |
| >-ninja
|   |
|   >-core
|
>-Ninja_client
| |
| >-ninja
|   |
|   >-client
.
.
.

拥有 java 背景,我认为这是可能的,但事实证明(阅读:导入错误)这是行不通的。 this answer中指出,一般不可能同时有ninja.coreninja.client除非它们是同一个包 ninja 的子包,但它们不是。这导致:

方法一:

在生产环境中,我们希望能够安装 coreserver 但不能安装 clientcoreclient 但不是 server。我可能错了,但据我了解 python 包,方法 A 不可能做到这一点。保持项目独立但兼容,使用名称为 ninja_core 的包似乎很有用,ninja_clientninja_server,这实际上解决了导入问题,并且在开发设置中一切顺利 运行。为了满足能够独立安装serverclient的需求,我想到了:

方法 B:

到目前为止我还没有让它工作,我认为它甚至不可能。我在想这样的事情:

# __init__.py of ninja
import ninja_core as core
# or this:
from ninja_core import core
# or this:
import ninja_core.core

我尝试了这些,但再次出现导入错误。在谷歌搜索组合 python 包的方法后,没有找到与我的问题相关的任何内容,我来到这里。

我在想,也许整件事都是设计错误。如果 clientserver 可以独立安装,它们是否应该在同一个包中?希望能够独立安装客户端和服务器是不是一个坏主意?为什么我可以 扩展 java 中的包,但不能扩展 python 中的包?这背后的想法是什么?

tl;dr

我正在开发 Ninja 库,用户应该可以在其中执行 import ninja.clientimport ninja.server。需要能够分别为 clientserver 安装库。如何实现这一目标?

假设您将顶级命名空间 ninja 留空,Python 3.3 及更高版本已原生支持此功能,请参阅 PEP 420;您所要做的就是创建 ninja 目录并 删除该目录中的 __init__.py 文件 :

eclipse_workspace
|
>-Ninja_core
| |
| >-ninja
|   |
|   >-core
|       |
|       >-__init__.py
|
>-Ninja_client
| |
| >-ninja
|   |
|   >-client
|       |
|       >-__init__.py

除了子 coreclient 目录外,ninja 目录仍然是空的。这些目录 do__init__.py 个文件。

在早期的 Python 版本中,您可以使用 setuptools namespace packages 添加对命名空间的支持。 Zope 和 Plone 项目多年来一直使用 setuptools 发布命名空​​间包。

基本原则是确保您的项目是带有 setup.py 文件的包,并且安装在 development mode 中或作为最终产品。您的 ninja 目录 do 然后有一个 __init__.py 文件,但是这些 必须 仅包含以下行:

__import__('pkg_resources').declare_namespace(__name__)

每个项目的 setup.py 文件必须声明命名空间:

setup(
    # ...
    namespace_packages = ['ninja']
)