【问题标题】:How to create a nested package space for python packages?如何为 python 包创建嵌套包空间?
【发布时间】:2016-01-31 12:06:21
【问题描述】:

我正在将我们公司正在开发的 python 库重组为不同的组。为避免污染顶级模块命名空间,我想将所有内容分组在顶级“companyname”包下,因此我们将拥有“conname.utils”、“conname.qa”、“conname.api”等.其中一些预计将与我们的产品一起分发,或可公开安装。 'qa' 将纯粹是内部的。

Google 做了类似的事情。例如,protobuf 库在模块路径中以“google.protobuf”的形式提供。不过不是特别干净:protobuf包安装的.pth文件长这样:

import sys, types, os;p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('google',));ie = os.path.exists(os.path.join(p,'__init__.py'));m = not ie and sys.modules.setdefault('google', types.ModuleType('google'));mp = (m or []) and m.__dict__.setdefault('__path__',[]);(p not in mp) and mp.append(p)

我认为这样做是为了欺骗导入引擎,因为“google”目录中没有 __init__.py。但是……不优雅。

有没有完善的方法来实现这一点?我不介意让任何“coname-*”包都需要一个“coname-top”包来获取 __init__.py。我还不确定如何说服 setuptools 将包视为不在模块树的顶部,也不可能从一棵树创建子包。

为了澄清,我特别询问如何设置上述内容,以便例如可以与 coname-api 分开分发和安装 coname-qa。两者都依赖于 coname-tools 是合理的。

【问题讨论】:

标签: python setuptools module-packaging


【解决方案1】:

您要做的是创建一个命名空间包。您可以使用 setuptools 来完成此操作。

https://packaging.python.org/guides/packaging-namespace-packages/#pkgutil-style-namespace-packages

设置如下结构的目录:

coname-utils/
    setup.py
    coname/
        utils/
            __init__.py
            ...
        ...

coname-qa/
    setup.py
    coname/
        qa/
            __init__.py
            ...
        ...

coname-api/
    setup.py
    coname/
        api/
            __init__.py
            ...
        ...

有一些变化,具体取决于您打算用于部署的工具。您可以查看上面的链接以了解详细信息。

此目录结构将您希望单独安装的命名空间部分隔离开来。您还可以分别对不同的子包进行版本控制,这有助于维护。大概您的某些子包之间可能存在依赖关系。您可以将代码添加到一个子包,该子包依赖于另一个子包中的 api 成员,而该子包仅存在于该子包的某些版本中。在 setup.py 文件中,您可以定义需要哪些版本的依赖项。

有关如何编写 setup.py 的详细信息,请参阅setuptools documentation

设置完成后,您应该可以使用 setuptools 构建项目,并且可以单独安装 utils、qa、api 等。安装到环境中后,您可以使用“import coname.utils”导入它们, "import conname.qa" 等

【讨论】:

  • 这应该是认可的答案
【解决方案2】:
  1. 目录 a 需要是一个包。添加一个__init__.py 文件使其成为一个包,这比一个简单的目录更上一层楼。

  2. 目录b也需要是a的子包。添加__init__.py文件。

  3. 目录 test 也应该是一个包。很难说这是否有必要。通常最好将 Python 模块的每个目录都作为一个正式的包。

  4. 为了导入,包需要在 sys.path 上;这是从 PYTHONPATH 环境变量构建的。默认情况下,安装的站点包和当前工作目录(实际上)是唯一可以找到包的两个地方。

这意味着必须安装 a,或者,您当前的工作目录也必须是 a 上一级的包。

或者,您需要将 PYTHONPATH 环境变量设置为包含 a。

【讨论】:

  • 对不起,我想我需要澄清一下这个问题,我已经在上面进行了编辑以涵盖它。具体来说,如何设置以便可以创建、分发和安装单独的包,但它们共享一个共同的根目录,例如上面示例中的“conname”。
猜你喜欢
  • 2019-08-30
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 2020-04-30
  • 1970-01-01
  • 2021-04-01
相关资源
最近更新 更多