如何为 setuptools 分发创建嵌套的命名空间包

mas*_*ber 6 python namespaces setuptools package

我正在开发一个 python 项目,该项目将具有单独的可分发部分。

我已经能够通过制作命名空间包来实现我的部分目标。我有“sub1”和“sub2”,都在命名空间“lvl1”中。我可以使用“pip install -e”或python setup.py develop. 我可以用import lvl1.sub1和导入它们import lvl1.sub2

但是,该项目非常庞大,并且需要嵌套命名空间。我想import lvl1.lvl2.sub1import lvl1.lvl2.sub2。所以两个子包都在同一个命名空间(“lvl2”)中,它本身在一个命名空间(“lvl1”)中。

所需的概念结构:

lvl1/
    lvl2/
        sub1/
            code.py
            more_code.py
            ...
        sub2/
            code.py
            ...
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点以及如何做到这一点?

gdl*_*lmx 2

是的,有不止一种方法。请阅读PEP 420 中的“嵌套命名空间包”部分

在 python >= 3.3 中,创建嵌套命名空间的最简单方法是删除(不包含)__init__.py每个可分发部分中特定文件夹(“lvl1”和“lvl2”)中的文件。在每个 中setup.py,显式列出最深命名空间中的所有包。

“lvl1_part1/setup.py”

setup(
    name='lvl1_part1',
    ...
    zip_safe=False,
    packages=['lvl1.lvl2.sub1']
)
Run Code Online (Sandbox Code Playgroud)

“lvl1_part2/setup.py”

setup(
    name='lvl1_part2',
    ...
    zip_safe=False,
    packages=['lvl1.lvl2.sub2']
)
Run Code Online (Sandbox Code Playgroud)

用于测试的文件结构:

lvl1_part1/
           setup.py
           lvl1/
                lvl2/
                     sub1/
                          __init__.py
lvl1_part2/
           setup.py
           lvl1/
                lvl2/
                     sub2/
                          __init__.py
Run Code Online (Sandbox Code Playgroud)

为了使上述包兼容较旧的 python 版本,请将pkgutilmagic 文件添加到每个“lvl1”和“lvl2”文件夹中。

鸣谢:上面的例子修改自https://github.com/pypa/sample-namespace-packages/tree/master/pkgutil