python 的模块层次结构是否与目录结构相关?
Is python's module hierachy tied to directory structure?
将此视为 this question 的更精致版本。
似乎 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'
所以 init.py 不能完全改变模块层次结构;这是我所知道的 python 中最接近 'altering module hierachy' 的东西。
那么,有没有办法改变模块层次结构?如:
- 一种使
import mod_a.mod_c
成为有效导入语句的方法?
- 一种在任意路径中将某些 python 模块安装到某些导入路径的方法?
这可以通过修改 __path__
、pkgutil.extend_path
或其他方式来完成。
根据 documentation:
A package’s __path__
attribute is used during imports of its subpackages. Within the import machinery, it functions much the same as sys.path
, i.e. providing a list of locations to search for modules during import.
__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__
计算得出。
These 所以问答涵盖了更多关于使用 __path__
.
将此视为 this question 的更精致版本。
似乎 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'
所以 init.py 不能完全改变模块层次结构;这是我所知道的 python 中最接近 'altering module hierachy' 的东西。
那么,有没有办法改变模块层次结构?如:
- 一种使
import mod_a.mod_c
成为有效导入语句的方法? - 一种在任意路径中将某些 python 模块安装到某些导入路径的方法?
这可以通过修改 __path__
、pkgutil.extend_path
或其他方式来完成。
根据 documentation:
A package’s
__path__
attribute is used during imports of its subpackages. Within the import machinery, it functions much the same assys.path
, i.e. providing a list of locations to search for modules during import.
__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__
计算得出。
These 所以问答涵盖了更多关于使用 __path__
.