有关此问题的问题已 asked many times但恐怕我仍然无法理解为什么从子目录导入的模块在我从自己的目录调用模块时可以工作,但是当我从另一个目录导入它时,我得到 ModuleNotFoundError: No module named _nested_package
.这是确切情况:
tbrowne@nd2110:~/scratch$ tree
.
└── topmodule
├── __init__.py
├── main.py
├── nest
│ ├── __init__.py
│ └── nestmodule.py
└── topmodule.py
现在这是 main.py:
from topmodule import test_add_two
if __name__ == "__main__":
print(test_add_two(11, 12))
这里是topmodule.py:
from nest.nestmodule import add_two
def test_add_two(x, y):
return add_two(x, y)
if __name__ == "__main__":
print(test_add_two(1, 2))
这是nestmodule.py:
def add_two(x, y):
return x + y
现在,如果我从它自己的目录运行 main.py,没有问题:
tbrowne@nd2110:~/scratch/topmodule$ python3 main.py
23
但是,如果我移动到上面的目录,说scratch,并创建nesttest.py:
tbrowne@nd2110:~/scratch$ cat nesttest.py
from topmodule.topmodule import test_add_two
if __name__ == "__main__":
print(test_add_two(3, 4))
然后我运行它:
tbrowne@nd2110:~/scratch$ python3 nesttest.py
Traceback (most recent call last):
File "/home/tbrowne/scratch/nesttest.py", line 1, in <module>
from topmodule.topmodule import test_add_two
File "/home/tbrowne/scratch/topmodule/topmodule.py", line 1, in <module>
from nest.nestmodule import add_two
ModuleNotFoundError: No module named 'nest'
问题是,我想要将其与 Poetry 或其他包创建者一起打包,并且我希望从导入的任何地方使用 topmodule
,即使它已打包,也能够导入nest.nestmodule
的函数。
我希望通过非常明确地了解具体情况,有人可以帮助我了解如何做到这一点。我正在处理的真实项目(不是这个玩具类比示例)中更广泛的背景是我在其他 git 存储库中使用 git 子模块,并且这些子模块必须与主存储库一起打包。
最佳答案
这里有三个独立但交叉的问题:
- Python 3 不允许隐式相对导入,因此
from Nest.nestmodule import add_two
会自动出错,因为nest
不是顶级-级别包。 - 修复此问题后,将
main.py
作为文件运行就会出错,因为这样做会将其目录放入sys.path
,这确实使nest
成为一个顶级包,但不能与from .nest…
一起使用。将其放入包中意味着它是一个模块,因此必须使用-m
运行。 (这里仍然存在陷阱:有关__main__
的所有内容都在某种程度上被破坏了。) - 您正在使用子模块(大概是用于
nest
),这(意见!)一般来说是一个坏主意,并且(事实上)与任何代码都不兼容,nest
或其他,它认为它是一个顶级包(参见#1)。对于无法编辑的代码“修复”此问题将涉及将其安装为依赖项,而不是子包,无论如何,这都是您应该做的。
关于python - 嵌套包导入在从包目录内调用时有效,但在其他地方则无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70906506/