这个问题被多次询问,但在我的案例中,没有一个解决方案似乎有所帮助。
我有一个像这样的目录结构
my_project/
main.py
bootstrap/
__init__.py
boot.py
consumer/
__init__.py
main.py
位于顶层目录(myproject
)并执行python3 consumer/main.py
会引发错误:
Traceback (most recent call last):
File "consumer/main.py", line 7, in <module>
from bootstrap.boot import MyClass
ImportError: No module named 'bootstrap'
奇怪的是,使用解释器导入该模块按预期工作。从PyCharm运行代码也可以正常工作。
我尝试使用“完整路径”导入,例如from my_project.bootstrap.boot import MyClass
失败的ImportError
失败。我也试过使用相对导入,例如from .bootstrap.boot import MyClass
{/ 1}}也失败了SystemError: Parent module '' not loaded, cannot perform relative import
修复此问题的一个方法就是我在virtualenv export PYTHONPATH="/root/my_project"
脚本底部添加activate
答案 0 :(得分:4)
您收到此错误,因为模块搜索路径仅包含当前目录,而不包括其父目录;由于您的其他模块不在PYTHONPATH
中,因此无法导入。
您可以在脚本中打印sys.path
来自行查找。
我使用以下内容创建了一个目录t
:
$ tree
.
├── a.py
├── bar
│ ├── __init__.py
│ └── world.py
└── foo
├── hello.py
└── __init__.py
2 directories, 5 files
以下是hello.py
的来源:
$ cat foo/hello.py
import sys
print("I am in {}".format(__file__))
for path in sys.path:
print(path)
from bar.world import var
print(var)
现在看一下当我执行foo/hello.py
并尝试从bar/world.py
导入内容时会发生什么;
$ python foo/hello.py
I am in foo/hello.py
/home/burhan/t/foo
/usr/lib/python2.7
/usr/lib/python2.7/plat-x86_64-linux-gnu
/usr/lib/python2.7/lib-tk
/usr/lib/python2.7/lib-old
/usr/lib/python2.7/lib-dynload
/home/burhan/.local/lib/python2.7/site-packages
/usr/local/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages
Traceback (most recent call last):
File "foo/hello.py", line 6, in <module>
from bar.world import var
ImportError: No module named bar.world
从打印的路径可以看出,只列出了系统范围的Python库路径以及脚本的当前目录。这就是找不到bar.world
的原因。
要解决此问题,您可以调整PYTHONPATH或使用相对导入;例如:
$ PYTHONPATH=../t python foo/hello.py
I am in foo/hello.py
/home/burhan/t/foo
/home/burhan/t
/usr/lib/python2.7
/usr/lib/python2.7/plat-x86_64-linux-gnu
/usr/lib/python2.7/lib-tk
/usr/lib/python2.7/lib-old
/usr/lib/python2.7/lib-dynload
/home/burhan/.local/lib/python2.7/site-packages
/usr/local/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages
42
您注意到我在这里手动覆盖PYTHONTPATH
并添加脚本的公共父级(42
来自bar / world)。
要使用相对导入修复此问题,首先要在最顶层的目录中创建一个包,否则您将收到着名的Attempted relative import in non-package
错误;有关这方面的更多信息以及有关Python 3导入如何工作的详细信息,请查看:Relative imports in Python 3