2016-08-18 75 views
0

这个问题被问了很多次,但没有一个解决方案似乎对我的情况有所帮助。Python3导入问题

我有这样

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这也失败,修复此SystemError: Parent module '' not loaded, cannot perform relative import

一个黑客是当我的virtualenv activate脚本

+0

您是否尝试过? – danielfranca

+0

是的,我编辑了这个问题,谢谢。 – ivica

+1

尝试添加一个'__init __。py'到'MY_PROJECT /目录,看看是否有帮助 – dhdavvie

回答

4

您收到此错误,因为模块搜索路径只包括当前目录的底部添加export PYTHONPATH="/root/my_project",而不是其父母;由于您的其他模块不在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从酒吧/世界推出)。

为了解决这个问题,使用相对进口,你首先有一个建立在最上面的目录包,否则你会得到著名Attempted relative import in non-package错误;更多关于这和细节上的Python 3进口的作品,怎么也得看看:“从my_project.bootstrap进口MyClass的” Relative imports in Python 3

+1

您是否介意经历如何创建顶层的包? – dhdavvie