如何将模块用作命名空间包和特定子项目中类的容器?也就是说,我怎样才能直接从命名空间包而不是它的子包中导入一些东西?
一个例子可以使问题更清楚。
三个分包calc
假设我想创建一个名为 的命名空间包calc
,上面有三个项目(sscce : calcs.tar.gz)。在目录中找到的第一个calc-add
具有以下结构:
calc-add/calc/
calc-add/calc/add.py
calc-add/calc/__init__.py
的内容calc-add/calc/__init__.py
只是
__import__('pkg_resources').declare_namespace(__name__)
根据命名空间包的要求,add.py
只有以下功能:
def op(n1, n2):
return n1 + n2
目录下还有另一个项目,calc-sub
结构如下:
calc-sub/calc/
calc-sub/calc/sub.py
calc-sub/calc/__init__.py
该__init__.py
文件与前一个相同,sub.py
只有一个简单的功能:
def op(n1, n2):
return n1 - n2
最后,我有一个calc-main
包含以下内容的目录:
calc-main/calc/
calc-main/calc/main.py
calc-main/calc/__init__.py
同样,__init__.py
只有提到的行,但main.py
有以下代码:
import calc.add, calc.sub
def apply(n1, n2, op):
if op == "add":
return calc.add.op(n1, n2)
else:
return calc.sub.op(n1, n2)
我如何调用以及如何调用该apply()
函数
如果我使用如下设置调用 Python 解释器$PYTHONPATH
:
$ PYTHONPATH=$PYTHONPATH:../calc-add/:../calc-sub/ python
那么我可以apply()
这样称呼:
>>> import calc.main
>>> calc.main.apply(2, 3, 'add')
5
但是,我想apply()
直接从调用calc
,如下所示:
>>> import calc
>>> calc.apply(2, 3, 'add')
5
如果我将以下行添加到calc-main/calc/__init__.py
:
from main import apply
但是,setuptools 文档非常清楚:
您不得在命名空间包的 __init__.py 中包含任何其他代码和数据。即使它在开发过程中似乎可以工作,或者当项目安装为 .egg 文件时,当使用“系统”打包工具安装项目时它不会工作——在这种情况下,不会安装 __init__.py 文件,更不用说执行了。
那么如何在不打破文件限制的情况下获得我想要的东西__init__.py
呢?那可能吗?