Python3中的Python命名空间包

问题描述 投票:8回答:1

命名空间包的主题似乎对于初学者来说有点混乱,并且它的先前版本的Python以几种不同的方式实现它或者StackOverflow上的许多问答都是过时的并没有帮助。我正在寻找Python 3.5或更高版本的解决方案。

The scenario:

我正在将一堆Python代码重构为模块和子模块,并且努力使这些项目中的每一个都设置为在坐在同一名称空间中时彼此独立地运行。

我们最终将使用内部PyPi服务器,将这些软件包提供给我们的内部网络,并且不希望将它们与外部(公共)PyPi软件包混淆。

示例:我有2个模块,我希望能够执行以下操作:

from org.client.client1 import mod1
from org.common import config

反映的模块将分开:

存储库1:

org_client_client1_mod1/
  setup.py
  mod1/
    __init__.py
    somefile.py

存储库2:

org_common_config/
  setup.py
  config/
    __init__.py
    someotherfile.py

我的Git存储库已经设置为org_client_client1_mod1org_common_config,所以我只需要在包装和__init__.py文件上执行设置,我相信。

Questions:

#1

使用__init__.py,我应该使用哪些(如果有的话)?:

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

要么:

import pkg_resources
pkg_resources.declare_namespace(__name__)

#2

使用setup.py,我还需要添加namespace_modules参数,如果是这样,我会使用namespace_modules=['org.common']namespace_modules=['org', 'common']吗?

#3

我可以通过以某种方式实现这一点而放弃以上所有内容吗?也许是更简单或更“pythonic”的东西?

python python-3.x setuptools pypi
1个回答
1
投票

这是一个艰难的主题。所有的-___init__.py到处都不能让我们感到轻松。

首先,我会回答你的问题:

使用__init__.py,我应该使用哪些(如果有的话)?

  • __init__.py可以完全是空的,它只需要在正确的位置。即(双关语)它们应该在任何包含python代码的子包中(不包括setup.py。)遵循这些规则你应该没问题。

使用setup.py,我是否还需要添加namespace_modules参数,如果是这样,我会使用namespace_modules=['org.common']namespace_modules=['org', 'common']吗?

  • 不!只有name=packages=。但是,请注意与目录结构进行比较的packages= arg的格式。
  • 这是package= arg:setup.py for namespace package的格式
  • 这是相应的目录结构:example_package/a/<subpackage>

我可以通过以某种方式实现这一点而放弃以上所有内容吗?也许是更简单或更“pythonic”的东西?

  • 如果您希望能够单独安装多个功能,但是在相同的顶级命名空间下,那么您就是在正确的轨道上。

我将花费其余的答案以原生格式重新实现您的命名空间包:

我会把所有有用的文档放在帖子的底部。

K所以我假设你想要原生命名空间包。首先让我们看看你的2个回购的当前结构:

org_client_client1_mod1/
  setup.py
  mod1/
    __init__.py
    somefile.py

&

org_common_config/
  setup.py
  config/
    __init__.py
    someotherfile.py

这个^太简单了!

得到你想要的:

我的大脑没有足够的弹性来知道我们是否可以使用命名空间包进行3级深度处理,但要做你想做的事情,这就是我非常肯定你想做的事情:

org-client/
  setup.py
  org/
    client/
      client1/
        __init__.py
        mod1/
          __init__.py
          somefile.py

&

org-common-but-also-note-this-name-doesnt-matter/
  setup.py
  org/
    common/
      __init__.py
      config/
        __init__.py
        someotherfile.py

基本上关键是要在每个name=内部指定正确的packages=stuptools.setup() args到setup.py

这些将是:

name='org_client',
...
packages=['org.client']

&

name='org_common'
...
packages['org.common']

分别。

然后在每个顶级目录中安装每个pip install .

安装第一个模块可以访问somefile.py模块,安装第二个模块可以访问someotherfile.py。您也不会对尝试在同一环境中安装名为org的2个软件包感到困惑。

K所以文档中最有用的部分:https://packaging.python.org/guides/packaging-namespace-packages/#packaging-namespace-packages

接下来我就是这样理解的:https://github.com/pypa/sample-namespace-packages/tree/master/native

© www.soinside.com 2019 - 2024. All rights reserved.