我正在尝试运行一个脚本,该脚本会启动一个 python 脚本等。我得到一个 ImportError: No module named ...,但是,如果我启动 ipython 并通过解释器以相同的方式导入相同的模块,则该模块被接受。
发生了什么事,我该如何解决?我试图了解 python 如何使用 PYTHONPATH,但我完全糊涂了。任何帮助将不胜感激。
-v
选项启动 python,您将看到 python 在哪里(或不在哪里)找到您导入的模块。
这个问题是由于命令行 IPython 解释器使用当前路径的方式与单独进程的方式(无论是 IPython 笔记本、外部进程等)的方式。 IPython 将寻找不仅可以在您的 sys.path 中找到的要导入的模块,而且还可以在您当前的工作目录中找到。从命令行启动解释器时,您正在操作的当前目录与您启动 ipython 的目录相同。如果您运行
import os
os.getcwd()
你会看到这是真的。
但是,假设您使用的是 ipython 笔记本,运行 os.getcwd()
,而您当前的工作目录是您在 ipython_notebook_config.py 文件中告诉笔记本进行操作的文件夹(通常使用 c.NotebookManager.notebook_dir
设置)。
解决方案是为 python 解释器提供 path-to-your-module。最简单的解决方案是将该路径附加到您的 sys.path 列表中。在您的笔记本中,首先尝试:
import sys
sys.path.append('my/path/to/module/folder')
import module_of_interest
如果这不起作用,则您手上遇到了与导入路径无关的不同问题,您应该提供有关您的问题的更多信息。
解决这个问题的更好(和更持久)的方法是设置你的 PYTHONPATH,它为解释器提供了额外的目录来查找 python 包/模块。将 PYTHONPATH 编辑或设置为全局变量取决于操作系统,此处针对 Unix 或 Windows 进行了详细讨论。
运行 python 项目时,只需在显示错误的文件夹下创建一个名为 __init__.py
的空 python 文件。
foo.ipynb
使用 bar/baz.py
,添加空的 bar/__init__.py
文件以便笔记本可以使用 from bar.baz import MyClass
确保他们都使用相同的解释器。这在 Ubuntu 上发生在我身上:
$ ipython3 -c 'import sys; print(sys.version)'
3.4.2 (default, Jun 19 2015, 11:34:49) \n[GCC 4.9.1]
$ python3 -c 'import sys; print(sys.version)'
3.3.0 (default, Nov 27 2012, 12:11:06) \n[GCC 4.6.3]
并且 sys.path
在两个解释器之间是不同的。为了修复它,我删除了 Python 3.3。
pip install --upgrade ipython
来获取最新版本,然后默认情况下它会自动使用 2.7.11。
import sys; sys.version
主要原因是 Python 和 IPython 的 sys.paths 不同。
请参考lucypark link,该解决方案适用于我的情况。它发生在安装opencv时
conda install opencv
在 iPython 中出现导入错误,解决此问题的三个步骤:
import cv2
ImportError: ...
1. 使用以下命令检查 Python 和 iPython 中的路径
import sys
sys.path
你会发现 Python 和 Jupyter 的结果不同。第二步,只需使用 sys.path.append
通过试错法修复错过的路径。
2.临时解决方案
在 iPython 中:
import sys
sys.path.append('/home/osboxes/miniconda2/lib/python2.7/site-packages')
import cv2
ImportError:..
问题已解决
3.永久解决方案
创建一个 iPython 配置文件并设置初始附加:
在 bash 外壳中:
ipython profile create
... CHECK the path prompted , and edit the prompted config file like my case
vi /home/osboxes/.ipython/profile_default/ipython_kernel_config.py
在 vi 中,附加到文件:
c.InteractiveShellApp.exec_lines = [
'import sys; sys.path.append("/home/osboxes/miniconda2/lib/python2.7/site-packages")'
]
完毕
执行 sys.path.append('my-path-to-module-folder')
会起作用,但为了避免每次您想使用该模块时都必须在 IPython 中执行此操作,您可以将 export PYTHONPATH="my-path-to-module-folder:$PYTHONPATH"
添加到您的 ~/.bash_profile
文件中。
这就是我修复它的方法:
import os
import sys
module_path = os.path.abspath(os.getcwd() + '\\..')
if module_path not in sys.path:
sys.path.append(module_path)
在安装ipython之前,我通过easy_install安装了模块;说sudo easy_install mechanize
。
安装 ipython 后,我不得不重新运行 easy_install 以便 ipython 识别模块。
如果您从命令行运行它,有时 python 解释器不知道查找模块的路径。
下面是我的项目的目录结构:
/project/apps/..
/project/tests/..
我在命令下面运行:
>> cd project
>> python tests/my_test.py
运行上述命令后,我得到以下错误
no module named lib
lib 被导入 my_test.py
我打印了 sys.path 并发现我正在处理的项目路径在 sys.path 列表中不可用
我在脚本 my_test.py
的开头添加了以下代码。
import sys
import os
module_path = os.path.abspath(os.getcwd())
if module_path not in sys.path:
sys.path.append(module_path)
我不确定这是否是解决它的好方法,但它确实对我有用。
os.getcwd()
获取的是运行脚本的目录,而不是脚本文件所在的目录。
我发现这个问题的解决方案在这里被广泛记录:
https://jakevdp.github.io/blog/2017/12/05/installing-python-packages-from-jupyter/
基本上,您必须在 Jupyter 环境中安装软件包,发出 shell 命令,例如:
!{sys.executable} -m pip install numpy
请检查上面的链接以获得权威的完整答案。
发生这种错误很可能是由于 python 版本冲突。例如,如果您的应用程序仅在 python 3 上运行并且您也获得了 python 2,那么最好指定要使用的版本。例如使用
python3 .....
代替
python
有一个类似的问题,通过调用 python3
而不是 python
来修复它,我的模块在 Python3.5 中。
我发现了这种差异的另一个来源:
我在本地和通常在 virtualenvs 中都安装了 ipython。我的问题是,在一个新制作的带有 ipython 的 virtualenv 中,系统 ipython 被拾取,它与 virtualenv 中的 python 和 ipython 版本不同(2.7.x 与 3.5.x),然后是欢闹。
我认为,每当安装将在 yourvirtualenv/bin
中包含二进制文件的东西时,明智的做法是立即为您使用的任何 shell 运行 rehash
或类似的东西,以便选择正确的 python/ipython。 (必须检查是否有合适的 pip
安装后挂钩...)
没有脚本的解决方案:
打开 Spyder -> Tools -> PYTHONPATH manager 通过单击“Add Path”添加 Python 路径。例如:'C:\Users\User\AppData\Local\Programs\Python\Python37\Lib\site-packages' 单击“同步...”以允许其他程序(例如 Jupyter Notebook)使用步骤 2 中设置的 pythonpaths。如果 Jupyter 已打开,请重新启动它
这可能是由于您的系统上安装了不同的python 版本,即python2 或python3 造成的。
运行命令 $ pip --version
和 $ pip3 --version
以检查 pip 来自 Python 3x。例如,您应该看到如下版本信息:
pip 19.0.3 from /usr/local/lib/python3.7/site-packages/pip (python 3.7)
然后使用以下命令运行 example.py
脚本
$ python3 example.py
目录 utils
发生在我身上。我试图将此目录导入为:
from utils import somefile
utils
已经是 python 中的一个包。只需将您的目录名称更改为不同的名称,它应该可以正常工作。
这个答案适用于这个问题,如果
您不想更改代码您不想永久更改 PYTHONPATH
下面的路径可以是相对的
PYTHONPATH=/path/to/dir python script.py
import sys
sys.path.append('/Users/{user}/Library/Python/3.7/lib/python/site-packages')
import ta
如果有人在 MSVS 代码中使用带有 Jupyter Notebook 的 conda
遇到此问题,解决方案是确保您使用的是正确的内核。内核位于界面右上角的一个框中,如下所示:
https://i.stack.imgur.com/1obWW.png
我指出我的 Python 版本也与我的应用程序路径匹配——问题解决了!
出现此问题是由于不同的版本 - 例如,如果您机器上安装的 Python 安装在名为 path_to_lib/python3.6
的文件夹中,但您的笔记本在 Python 3
中运行 - 命名中的间距很重要!
如何解决?
创建新的 jupyter notebook 时,只需选择与您的版本相同的 Python(注意空格!)。见附图。
https://i.stack.imgur.com/OecV7.png
这对我有用:我刚刚更改了笔记本中的工作目录
import os
os.chdir("my/path/to/module")
os.getcwd()
我的 Jupyter Lab 设置也有类似问题,我通过检查 Jupyter Lab 打开时的日志解决了这个问题。这告诉我虚拟环境 (pipenv) 无法找到 Jupyter Lab,因此它使用了共享版本(来自早期安装的 Python)。
我创建了一个 requirements.txt,发现我没有在这个新环境中安装 Jupyter Lab。安装它解决了导入错误。
删除 pathlib
并重新安装。删除 sitepackages
文件夹中的 pathlib 并使用 pip 命令重新安装 pathlib 包:
pip install pathlib
不定期副业成功案例分享
__init_.py
,对吗? ...并且,不会想要修改PYTHONPATH
或调用sys.path.append
,即使它们也是正确的(正确的?)。我的意思是,我有几十个目录,其中包含代码,我不会将它们全部添加到路径中——或者期望其他用户添加到他们的 jupyter 配置文件中,即使它是一个目录。