Python 导入错误

4 投票
4 回答
21991 浏览
提问于 2025-04-16 03:07

我的导入有什么问题呢?

应用程序的文件夹结构如下:

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__.pymyapp/models/__init__.pymyapp/tests/__init__.py 里都有 __init__.py 文件,并且正如前面提到的,使用 nosetests 运行单元测试时一切正常。

4 个回答

1

你是怎么执行 import.py 的?当你执行的时候,当前的工作目录是什么?

要想使用 import 导入 myapp 这个目录,myapp 必须在 Python 的 路径 中(也就是说,它得在 sys.path 列出的某个目录里)。Python 在启动时会自动把当前的工作目录加到路径列表里。

所以,如果包含 myapp 的目录没有手动添加到路径中(比如通过设置 PYTHONPATH 环境变量,或者在 sitecustomize.py 中把它加到 sys.path),那么你在运行脚本的时候就需要在包含 myapp 的目录里。如果你在 myapp 目录里面,你就无法导入 myapp 这个包。

1

你的 sys.path 在运行测试和运行脚本时显然设置得不一样。你可以在两个模块的顶部加上

import sys
print(sys.path)

来确认这一点。然后,修正那个错误的设置(如果缺少的话,就把 myapp 的父目录添加到 sys.path 中)。

4

这里应该是 __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 第一个条目的不同。

撰写回答