python名称空间包的当前状态

Ach*_*him 13 python distutils namespace-package

我想在一个主模块中有几个python子模块,但是我想将它们作为单独的python软件包分发。因此,程序包A应该提供“ my_data.source_a”,程序包B应该提供“ my_data.source_b”,等等。

我发现我必须为此使用一个名称空间包,但是试图弄清楚细节,我发现了多个解决该问题的PEP。PEP 420似乎是最新的,它是基于PEP 402和PEP 382建立的。

对我来说,尚不清楚实现的不同PEP的状态。所以我的问题是:http : //pythonhosted.org/distribute/setuptools.html#namespace-packages仍然是解决之道,还是应该如何构建我的命名空间包?

ost*_*ach 10

Python文档有使用Python创建命名空间中的软件包,包括何时使用每个三种方法的指导方针的三个方面一个很好的说明。此外,在另一个StackOverflow 线程中对此主题进行了深入讨论,该线程具有良好的接受度。最后,如果您是宁愿阅读代码而不是文档的人,则该sample-namespace-packages回购包含使用三种可用方法中的每种方法创建的名称空间包的示例。

简而言之,如果您打算让您的程序包与Python 3.3及更高版本一起使用,则应使用本机名称空间程序包方法。如果您打算让软件包与旧版Python一起使用,则应使用pkgutil方法。如果打算将名称空间包添加到已经使用该pkg_resources方法的名称空间,则应继续使用method。


使用本机名称空间包,我们可以__init__.py从这两个包中删除并修改setup.py文件,如下所示:

# setup.py file for my_data.source_a
from setuptools import setup, find_namespace_packages

setup(
    name="my_data.source_a",
    version="0.1",
    packages=find_namespace_packages(include=['my_data.*'])
)
Run Code Online (Sandbox Code Playgroud)
# setup.py file for my_data.source_b
from setuptools import setup, find_namespace_packages

setup(
    name="my_data.source_b",
    version="0.1",
    packages=find_namespace_packages(include=['my_data.*'])
)
Run Code Online (Sandbox Code Playgroud)

我们需要添加的include=['my_data.*']参数,因为在默认情况下find_namespace_packages()是在文件夹而宽松,这包括作为命名的包,如所描述这里

对于支持Python 3.3及更高版本的软件包,这是推荐的方法。


使用pkgutil-style名称空间软件包,我们需要my_data.__init__.py将以下行添加到每个软件包中的文件中:

__path__ = __import__('pkgutil').extend_path(__path__, __name__)
Run Code Online (Sandbox Code Playgroud)

这是backports名称空间和存储库中不同包google-cloud-python使用的方法,并且是支持较旧版本的Python的推荐方法。


abd*_*wer 5

Python的最新版本是3.7,它使用本机名称空间包方法来创建在PEP 420中定义的名称空间包。

当前有三种创建名称空间包的方法:

  1. 使用本地名称空间包。这种类型的名称空间包在PEP 420中定义,并且在Python 3.3和更高版本中可用。如果命名空间中的软件包仅需要支持Python 3并通过进行安装,则建议使用此选项pip
  2. 使用pkgutil样式的名称空间包。此建议适用于需要同时通过支持Python 2和3,安装新的软件包pippython setup.py install
  3. 使用pkg_resources样式的名称空间包。如果您需要与已经使用此方法的软件包兼容,或者您​​的软件包需要使用zip安全,则建议使用此方法。

参考:打包名称空间包