我有以下难题。我试图在父包级别从包的子包中公开一些模块。
文件夹结构基本上是这样的:
script.py
package/
__init__.py
module1.py
subpackage/
__init__.py
submodule1.py
submodule2.py
在我目前必须编写的script.py
文件中
from package.subpackage.submodule1 import foo
如果我想从submodule1.py
文件中导入某些内容,但我希望能够在包级别公开文件submodule1.py
和submodule2.py
,这样我的所有导入都可以看起来像
from package.module1 import bar
from package.submodule1 import foo
from package.submodule2 import goo
请注意,我不想在bar
级别公开foo
,goo
和package
,即不
from package import bar
from package import foo
因为在我的情况下,模块之间的分离仍然很重要。
这甚至可能吗? __init__.py
文件中有诀窍吗?
谢谢!
答案 0 :(得分:5)
为了您的目的,python模块只是名称空间。也就是说,模块的全局变量中的所有内容都可以导入并用作module.thingy
。您可能已经注意到,在许多模块中,您还可以找到一些内置函数。例如,logging.os
只是常规os
模块。
因此,在您的包(package/__init__.py
)中导入您想要的任何内容,并将其绑定到您要将其公开为的名称。
# package/__init__.py
# import package.module1 as module1 # one *can* do this, but its at best without benefit (see comments)
import package.subpackage.submodule1 as submodule1
import package.subpackage.submodule2 as submodule2
这样可以import package.submodule1
和import package.submodule1 as foo
。
请注意,这种简单的方式不允许您执行from package.submodule1 import bar
。为此,您需要一个实际的虚拟模块。
# package/submodule1/__init__.py
from package.subpackage.submodule1 import *
答案 1 :(得分:3)
是的,这是可能的 让我们一步一步看看会发生什么;
from package.submodule1 import foo
时,会检查sys.modules
是否有package
。 package/__init__.py
正在运行并加载sys.modules
检查package.submodule1
package/submodule1.py
是否存在。我们可以在步骤2中为sys.modules
package.submodule1
中输入一个条目来完成第3步。
package/__init__.py
import sys
from .subpackage import submodule1
from .subpackage import submodule2
for module in (submodule1, submodule2):
full_name = '{}.{}'.format(__package__, module.__name__.rsplit('.')[-1])
sys.modules[full_name] = sys.modules[module.__name__]