Python 使用父包名称导入子包时发生ModuleNotFound错误

Python 使用父包名称导入子包时发生ModuleNotFound错误,python,python-import,Python,Python Import,我正在尝试根据推荐的项目结构对已建立的Python项目进行建模 切换到这个新结构后,我现在需要使用$python3-m sample.runner运行脚本,而不仅仅是$python3 runner.py,否则我会得到一个ModuleNotFoundError。我试图理解为什么会这样,以及是否可以避免这种情况 使用新结构运行$python3 runner.py,我可以: $ python3 runner.py Traceback (most recent call last): File &

我正在尝试根据推荐的项目结构对已建立的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测试。如果没有它,使用tox运行测试将失败,并显示
ModuleNotFoundError:没有名为'subpkg1'的模块
消息。我猜这是因为我从repo_root运行tox,但我不确定

runner.py

from sample.subpkg1 import subpkg1_file1 

def main():
    subpkg1_file1.print_subpkg1()


if __name__ == "__main__":
    main()
subpkg1_file1.py(尽管这不重要):


sample
模块不知道,因为Python不知道在哪里查找它;它不是在蟒蛇中。如果需要,可以在脚本开头扩展它:

导入系统 如果“样本”不在sys.modules中: 从操作系统导入路径为osp sys.path.insert(0,osp.dirname(osp.dirname(_文件__))) delos,sys 从sample.subpkg1导入subpkg1_文件1 def main(): 子文件1\u文件1.打印子文件1() 如果名称=“\uuuuu main\uuuuuuuu”: main() ```
好的,我想这就解释了为什么使用
$python-m
运行它会起作用。根据位于的文档,“与-c选项一样,当前目录将被添加到sys.path的开头。”我觉得奇怪的是,在没有讨论这些副作用的情况下推荐这个项目结构。
def print_subpkg1():

    print("Printing from subpkg1!")