ImportError: 没有名为的模块"错误似乎与我的代码无关
我正在尝试完成《Learn Python The Hard Way, 2nd Edition》中的第47个练习,但当我运行tests/ex47_tests.py
时遇到了错误:
File "tests/ex47_tests.py", line 3, in <module>
from ex47.game import Room
ImportError: No module named ex47.game
我以为是我在代码中做错了什么,因为我对这些还很陌生,所以我从一个在GitHub上看起来成功完成了这个练习的用户那里克隆了这个仓库。
不仅我们代码中相关的部分是完全一样的,当我尝试运行我从他那里克隆的tests/ex47_tests.py
时也出现了同样的错误。所以现在我感到很困惑,希望有人能给我一个解决方案。有什么想法吗?
6 个回答
这本书让你复制一个叫“skeleton”的文件夹,然后用它来做游戏房间的练习(第47题)。这个skeleton文件夹里面有一个叫“NAME”的文件夹。
所以,如果你复制了skeleton文件夹并把它命名为ex47,那么在ex47里面就会有另一个ex47文件夹。
lpthw > ex47 > ls
bin docs ex47 setup.py tests
当书里说“接下来,创建一个简单的文件ex47/game.py,把测试代码放进去”时,你可能会以为是在最外层的ex47文件夹里。其实这样理解是不对的!这就是为什么导入的时候会出问题。
我也遇到过同样的问题,直到我意识到书里把外层的文件夹(也就是我们通过复制skeleton得到的那个)称作“simplegame”,这在书中的一句话里可以看出来 -
~/projects/simplegame $ nosetests
所以关于PYTHONPATH的所有回答都是正确的,我只是想解释一下为什么你的导入会不成功!
fabrizioM的回答应该能让它正常工作。这里有个简单的解释。
当Python加载一个文件时,它会在文件系统中搜索。所以这里有一个导入语句:
from ex47.game import Room
它会在模块搜索路径上寻找ex47.py这个文件(在Python代码中可以通过sys.path访问这个路径)。模块搜索路径包含了一些目录,这些目录是根据Python的安装情况、PYTHONPATH环境变量中列出的目录,以及你正在执行的脚本的父目录来决定的。它在路径上找不到ex47.py,但发现有一个名为ex47的目录,里面有一个__init__.py
文件。然后它在这个文件夹里找到了game.py。
问题是你当前的文件夹不在模块搜索路径上。因为ex47_tests.py被运行时,它的路径是$cwd/tests。你需要把$cwd加到路径上。
PYTHONPATH=. python tests/ex47_tests.py
这个做的正是这个。它把$cwd加到模块搜索路径上,这样Python就能找到源文件了。
你也可以这样做:
python -m tests.ex47_tests
这样会把它当作一个模块来运行,而不是一个文件,同时它会自动把当前目录作为路径加到模块搜索路径中,而不是文件所在的目录。
在你的代码库目录下:
PYTHONPATH=. python tests/ex47_tests.py
确保你的路径中没有其他的 ex47.py 文件或包。