Python 导入错误
我的导入有什么问题呢?
应用程序的文件夹结构如下:
myapp/
- models/models.py 文件里包含了
SpotModel()
- tests/tests.py 文件里包含了 TestSpotModel(unittest.TestCase)。tests.py 里导入了
from myapp.models.models import *
,这个运行得很好 - scripts/import.py 文件里也包含了
from myapp.models.models import *
问题是,当执行 import.py 时会出现错误:
ImportError: No module named myapp.models.models
但是 tests.py 可以正常运行。
我在 myapp/__init__.py
、myapp/models/__init__.py
和 myapp/tests/__init__.py
里都有 __init__.py
文件,并且正如前面提到的,使用 nosetests 运行单元测试时一切正常。
4 个回答
你是怎么执行 import.py
的?当你执行的时候,当前的工作目录是什么?
要想使用 import
导入 myapp
这个目录,myapp
必须在 Python 的 路径 中(也就是说,它得在 sys.path
列出的某个目录里)。Python 在启动时会自动把当前的工作目录加到路径列表里。
所以,如果包含 myapp
的目录没有手动添加到路径中(比如通过设置 PYTHONPATH
环境变量,或者在 sitecustomize.py
中把它加到 sys.path
),那么你在运行脚本的时候就需要在包含 myapp
的目录里。如果你在 myapp
目录里面,你就无法导入 myapp
这个包。
你的 sys.path
在运行测试和运行脚本时显然设置得不一样。你可以在两个模块的顶部加上
import sys
print(sys.path)
来确认这一点。然后,修正那个错误的设置(如果缺少的话,就把 myapp
的父目录添加到 sys.path
中)。
这里应该是 __init__.py
,而不是 init.py
。确保每个目录里都有这个文件,这样才能正常导入。
编辑:我成功复现了这个问题。以下是目录结构:
cesar@cesar-laptop:/tmp/asdasd$ tree . `-- myapp |-- __init__.py |-- models | |-- __init__.py | `-- models.py |-- scripts | |-- data.py | `-- __init__.py `-- tests |-- __init__.py `-- tests.py
我在 data.py
的最开始放入了以下代码,以便缩小问题范围:
import sys
import pprint
pprint.pprint(sys.path)
from myapp.models.models import *
按照提问者的方式运行 data.py
会出现导入错误:
cesar@cesar-laptop:/tmp/asdasd$ python myapp/scripts/data.py ['/tmp/asdasd/myapp/scripts', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', -- Skipped -- '/usr/local/lib/python2.6/dist-packages'] Traceback (most recent call last): File "myapp/scripts/data.py", line 6, in from myapp.models.models import * ImportError: No module named myapp.models.models
但是这样做就能正常工作:
cesar@cesar-laptop:/tmp/asdasd$ python -m myapp.scripts.data ['', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', -- Skipped -- '/usr/local/lib/python2.6/dist-packages']
注意 sys.path
第一个条目的不同。