Python错误 "ImportError: No module named"

621

Python已安装在本地目录。

我的目录树看起来像这样:

(local directory)/site-packages/toolkit/interface.py

我的代码在这里:

(local directory)/site-packages/toolkit/examples/mountain.py

为了运行这个示例,我会写 python mountain.py,而在代码中我有以下内容:

from toolkit.interface import interface

然后我收到了以下错误:

Traceback (most recent call last):
  File "mountain.py", line 28, in ?
    from toolkit.interface import interface
ImportError: No module named toolkit.interface

我已经检查了sys.path,在那里我有目录/site-packages。此外,工具包文件夹中有文件__init__.py.bin来告诉Python这是一个包。我还在示例目录中有一个__init__.py.bin

我不知道为什么Python在sys.path中找不到该文件。有什么想法吗?可能是权限问题吗?需要一些执行权限吗?


4
确保你在Python中有该文件的读取权限。 参考链接:https://dev59.com/E2Qm5IYBdhLWcg3w6ShR#20999950 - cSn
2
请务必将您的目录标记为“资源根目录”,以便PyCharm知道这是一个包。 - Yushan ZHANG
在我的情况下,问题是新安装的模块的权限不是“755”。这是因为机器上的“umask”是“0027”,导致“其他人”没有“读取”权限,导致模块无法读取。添加“读取”权限解决了我的问题。建议在安装后检查目标目录的权限。 - anu
尝试访问以下网址: https://stackoverflow.com/questions/47887614/how-to-import-module-or-a-file-from-subfolder-in-python/47887660#47887660 - Rawan-25
我该如何将我的目录标记为“资源根目录”?https://stackoverflow.com/users/6829195/yushan-zhang - skittlebiz
显示剩余4条评论
38个回答

326

根据您对orip帖子的评论,我猜测发生了以下情况:

  1. 你在Windows上编辑了__init__.py文件。
  2. Windows编辑器添加了一些非打印字符,可能是回车符(Windows中的行尾为CR / LF;unix中只有LF),或者可能是CTRL-Z(Windows文件结束符)。
  3. 您使用WinSCP将文件复制到Unix系统。
  4. WinSCP认为:“这里有一些不是基本文本的东西;我会添加.bin扩展名来表示二进制数据。”
  5. 缺少__init__.py文件(现在称为__init__.py.bin),这意味着Python无法将工具包识别为一个包。
  6. 您在适当的目录中创建__init__.py文件,然后一切正常...?

64
另外,python -c 'import sys; print sys.path' 有时很有用 -- 用户有时会把文件放在未被扫描的路径中。 - mikebabcock
2
我使用的是相同的东西,只是WinSCP没有附加“.bin”后缀。 - user
15
如果我的"__init__.py"文件是空的,会发生相同的事情吗? - dietbacon
4
对我来说,问题在于我使用了 python driver.py,而应该使用 python3 driver.py,因为我是用 pip3 安装的。 - Eric Wiener
正如@EricWiener所指出的那样,使用Python 2也可能会导致此问题。他可能正在使用#!/usr/bin/env python来检测Python环境,并且将python2映射到python3,这会导致某些软件包中的错误。 - DGoiko
显示剩余2条评论

101

在LPTHW练习中,我遇到了非常相似的问题;Python从未承认我在调用文件的目录中有文件。但最终我成功了。我做了什么并且我建议你也这样尝试:

(注意:从您最初的帖子,我假设您正在使用基于*NIX的机器并从命令行运行事物,因此这个建议是针对这个情况量身定制的。由于我使用Ubuntu,所以我这样做)

  1. 更改目录(cd)到包含文件的目录的上一级目录。在这种情况下,您正在尝试运行mountain.py文件,并尝试调用toolkit.interface.py模块,它们位于不同的目录中。在这种情况下,您将进入包含这两个文件路径的目录(或者换句话说,这些文件的路径最接近的目录)。在本例中,这是toolkit目录。

  2. 当您进入toolkit目录时,在命令行上输入以下代码行:

    export PYTHONPATH=.

    这将设置PYTHONPATH为“。”,这基本上意味着您的PYTHONPATH现在将在您当前所在的目录中寻找任何被调用的文件(更确切地说,在您当前目录的子目录中寻找)。因此它不仅会在当前目录中查找,而且会在所有在您当前目录中的目录中查找)。

  3. 在完成上述步骤设置PYTHONPATH之后,从当前目录(即toolkit目录)运行您的模块。Python现在应该能够找到并加载您指定的模块。


6
在Windows上,可以使用命令set PYTHONPATH=.来设置Python路径。 - cjbarth
如果您的已有 PYTHONPATH 环境变量中含有第三方库或自定义库引用,请小心处理。如果确实需要,可以运行以下命令:set PYTHONPATH=%PYTHONPATH%;.; 表示将 . 添加到 PYTHONPATH 中,然后运行 echo %PYTHONPATH% 命令,该命令应显示 path\to\custom\library;.;。接着,在应用程序目录中使用 python applicationlaunchfile.py 命令运行您的应用程序。 - EliSquared
你救了我。谢谢!这也适用于2022年的Python 3.10。 - Radu Gheorghiu
为什么默认情况下PYTHONPATH中没有“.”:https://dev59.com/SGAf5IYBdhLWcg3woz9n#FrmkEYcBWogLw_1bQEBa - user202729

96

做什么

(local directory)/site-packages/toolkit

你有一个__init__.py文件吗?

为了让导入(import)“遍历(walk)”你的目录,每个目录都必须有一个__init__.py文件。


1
好观点!备注:自Python 3.3以来,任何在sys.path上的目录,只要其名称与包名称匹配,都会被识别。 - PatrickT
8
这只有在使用相对路径引用时才是必需的,为什么每个目录都必须有它? - Sonic Soul
自Python 3.3版本起,不再需要使用__init__.py文件(尽管它可能有其他影响并且经常需要)。请参阅 https://peps.python.org/pep-0420/。 - Karl Knechtel

46

在*nix系统上,还要确保PYTHONPATH正确配置,尤其是格式正确:

 .:/usr/local/lib/python

注意在开头要加入 .:,这样可以在当前目录下搜索。

根据版本,它也可能位于其他位置:

 .:/usr/lib/python
 .:/usr/lib/python2.6
 .:/usr/lib/python2.7 and etc.

6
根据版本不同,它也可能是 .:/usr/lib/python.:/usr/lib/python2.6.:/usr/lib/python2.7 等。 - Nikita Volkov
对我来说,该模块位于 /usr/local/lib/python3.4/dist-packages 中,但是当我在终端(Ubuntu)中键入 python3 并尝试导入它时,它不允许我这样做,并显示“ImportError: no module x exists”错误。 - user65165
在文件末尾添加 #!/usr/bin/python 也可以生效,对吗? - Nearoo
1
@Nearoo 我认为那样做不会起作用。此外,通常这个 shebang 是添加在文件的顶部。 - Renaud
-1 在PYTHONPATH中列出Python安装目录是明显错误的,表明对该变量用途的理解不足。 - Piotr Dobrogost
2
在MacOSX上,通过将PYTHONPATH=/usr/local/lib/python2.7/site-packages添加到启动脚本中来解决此问题。 - Johan Snowgoose

46

如果你正在阅读这篇回答,说明你的__init__.py文件已经放在正确的位置,你已经安装了所有的依赖项,但仍然遇到了ImportError错误。

我曾经遇到过类似的问题,当我在PyCharm中运行程序时,它可以正常运行,但是在终端中运行时会出现上述错误。在进一步调查后,我发现PYTHONPATH没有添加项目目录的条目。因此,我按照Import statement works on PyCharm but not from terminal设置了PYTHONPATH:

export PYTHONPATH=$PYTHONPATH:`pwd`  (OR your project root directory)

还有一种使用sys.path的方法:

import sys
sys.path.insert(0,'<project directory>') OR
sys.path.append('<project directory>')

您可以根据希望搜索项目的顺序使用插入/追加操作。


2
这是我作为解决方法所做的事情。但我仍然不明白为什么这是必要的。在我的Pipfile中,有一个相对路径模块,如果没有这个解决方法,它将无法被检测到(例如,我会得到ImportError)。 - Kevin Friedheim
2
太棒了。如果你确定已经在正确的路径下,可以尝试使用以下通用方法:sys.path.append(os.getcwd()) - Matt Elgazar
1
这确实是救命稻草。 - Dev
Python广告语:让难事变得简单,让简单变得困难。 - C.J.

32
使用 PyCharm(JetBrains 套件的一部分),您需要将脚本目录定义为源代码目录:
右键单击 > 标记目录为 > 源代码根目录

谢谢,这绝对是必要的。在继承遗留项目时,所有模块都位于 /src 目录之外的平级层次结构中。 - baumannalexj
这真是魔法! - t3chb0t

26

对我来说,这是一件非常愚蠢的事情。我使用 pip3 install 安装了库,但运行程序时使用的是 python program.py 而不是 python3 program.py


谢谢!如果你在一个默认安装Python2的系统上运行(如OS X),那么这可能是一个常见的错误。 - DeveloperRyan

26

我解决了自己的问题,并将总结出存在的问题和解决方案:

文件名必须为__init__.py。如果扩展名不同,例如我的情况是.py.bin,那么Python就不能浏览目录,也无法找到模块。要编辑这些文件,您需要使用Linux编辑器,例如vinano。如果您使用Windows编辑器,则会写入一些隐藏字符。

另一个影响的问题是,我安装了另一个Python版本。因此,如果有人正在使用本地安装的python,务必确保运行程序的Python安装是本地Python。要检查这一点,请执行which python,然后查看可执行文件是否在本地目录中。如果不是,请更改路径,但务必确保本地Python目录位于其他Python之前。


我遇到的问题是,一个模块被pip重新安装,只有root用户才能访问它,因此运行程序的用户看不到它。 - Jānis Elmeris
@JānisElmeris您能详细解释一下上面的评论吗?我认为我也遇到了类似的错误。我将我的__init__.py文件放在相关目录中,但是我使用setup.py手动安装了一个包。安装新包会如何干扰导入? - Krishna Oza
@darth_coder,抱歉,那已经是六年前的事了,我不记得具体情况了。而且,我最近很少使用Python。从我写的内容来看,我只能想到我以root身份安装了一个软件包,这可能会更改权限,导致其他用户无法像以前一样访问它们。 - Jānis Elmeris

21

一种简单的解决方案是使用 python -m pip install <library-name> 来安装模块,而不是使用 pip install <library-name>。 如果有管理员限制,您可以使用sudo。


4
python -mpip install 前面的作用是什么? - sporc
2
当你使用 -m 命令行标志时,Python 将为您导入一个模块或包,然后将其作为脚本运行。当您不使用 -m 标志时,您所命名的文件将只被视为一个脚本来运行。 - Tony Ciccarone
不确定这个答案想说什么关于python -m pip...可以工作,但是pip...不能:实际上,它们是相同的东西,假设它们实际上在相同的python目录中。可能观察到的情况是,在某些旧的Python版本中没有单独的pip程序(但现在在最新的2.7和3.x中有了)。在这种情况下,python位于本地虚拟环境中,而pip则不在其中,因此python -m pip install将会安装在本地虚拟环境中,而pip则会尝试在系统Python中安装(并且需要sudo进行安装)。无论哪种情况,这都没有意义。 - michael

21
要将一个目录标记为包,你需要一个名为__init__.py的文件。

1
init.py文件中有什么内容?请将其作为问题的一部分发布。 - S.Lott
什么也没有,它是空的,它是我下载的包里面的,我需要在文件中写些什么吗? - Eduardo
@S.Lott:你不需要在 init.py 文件中添加任何内容,对吗? - igorgue
1
@Eduardo。你的__init__.py出现了错误。而你说它是空的。这很难协调。并且它不能被称为__init__.py.bin——Python会忽略这个文件。通常情况下,它可以什么都没有。 - S.Lott
谢谢你的建议。我通常使用nano进行编辑,但我使用Windows编辑器的原因是我在集群中工作,并且我使用WinSCP移动文件,有时我会使用那个编辑器来更改文件。 - Eduardo
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接