使用父包名称导入子包时出现 ModuleNotFoundError

ModuleNotFoundError when importing subpackage using parent package name

我正在尝试根据 https://docs.python-guide.org/writing/structure/.

推荐的项目结构为已建立的 Python 项目建模

切换到这个新结构后,我现在需要 运行 使用 $ python3 -m sample.runner 而不是 $ python3 runner.py 的脚本,否则我会得到 ModuleNotFoundError。我想了解为什么会这样,是否可以避免?

使用新结构运行 $ python3 runner.py 得到:

$ python3 runner.py 
Traceback (most recent call last):
  File "runner.py", line 1, in <module>
    from sample.subpkg1 import subpkg1_file1 
ModuleNotFoundError: No module named 'sample'

旧项目结构:

repo_root:
 | 
 |  |
 | ./subpkg1:
 |  | __init__.py
 |  | subpkg1_file1.py
 |  |
 | ./test:
 |  | __init__.py
 |  | bar.py
 |  |
 | runner.py
 | .coveragerc
 | README.md
 | tox.ini
 | 

新项目结构:

repo_root:
 | 
 | ./sample:
 |  | __init__.py
 |  | runner.py
 |  |
 |  | ./subpkg1:
 |  |  | __init__.py
 |  |  | subpkg1_file1.py
 |  |
 | ./test:
 |  | __init__.py
 |  | bar.py
 |  |
 | .coveragerc
 | README.md
 | tox.ini
 | 

我用 sample 更新了 runner.py 中的导入以满足毒性测试。没有它,使用 tox 的 运行ning 测试会失败并显示 ModuleNotFoundError: No module named 'subpkg1' 消息。我的猜测是因为我 运行ning tox 来自 repo_root,但我不确定。

runner.py

from sample.subpkg1 import subpkg1_file1 

def main():
    subpkg1_file1.print_subpkg1()


if __name__ == "__main__":
    main()

subpkg1_file1.py(虽然这不重要):

def print_subpkg1():

    print("Printing from subpkg1!")

不知道sample模块,因为Python不知道去哪里找;它不在 PYTHONPATH 中。如果需要,您可以在脚本的开头扩展它:

import sys
if 'sample' not in sys.modules:
    from os import path as osp
    sys.path.insert(0, osp.dirname(osp.dirname(__file__)))
del os, sys

from sample.subpkg1 import subpkg1_file1 

def main():
    subpkg1_file1.print_subpkg1()


if __name__ == "__main__":
    main()

```