可以认为这是一个更精细的版本 这个问题.
看来python的模块结构是和实际的文件目录挂钩的。虽然可以通过使用 __init__.py
这并不会改变实际模块的层次结构,因为就导入设施而言,这就是日志。
例如
some_dir
├ main.py
└ mod_a
├ __init__.py
└ mod_b
└ mod_c.py
mod_a/__init__.py
:
from .mod_b import mod_c
mod_a/mod_b/mod_c.py
:
def foo():
print("Foo!")
在这种情况下,我们可以在 main.py
:
from mod_a import mod_c
mod_c.foo()
但不是这个。
import mod_a.mod_c
mod_c.foo()
但不是这个:
Traceback (most recent call last):
File "main.py", line 1, in <module>
import mod_a.mod_c
ModuleNotFoundError: No module named 'mod_a.mod_c'
所以 启动.py不能完全改变模块的层次结构;而这是我所知道的python中最接近 "改变模块层次结构 "的地方。
那么,有没有一种方法可以改变模块的层次结构?比如说
import mod_a.mod_c
一个有效的导入语句?这可以通过修改 __path__
,与 pkgutil.extend_path
或以其他方式。
根据 文件:
一揽子计划
__path__
属性在其子包的导入过程中使用。在导入机制中,它的功能与sys.path
即提供一个位置列表,以便在导入时搜索模块。
__path__
可以在模块的 __init__.py
来改变导入系统搜索子模块的位置。
在给定的情况下,使用 pkgutil.extend_path
:
# mod_a/__init__.py
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__ + '.mod_b')
或通过修改: __path__
手动。
# mod_a/__init__.py
__path__.append("(...)/some_dir/mod_a/mod_b")
其中实际路径为: mod_b
最好从以下方面计算 __file__
.
这些 SO的问题和答案涵盖了更多关于使用 __path__
.