首页 > 解决方案 > 仅使用 IPython 时出现 ImportError

问题描述

我有一个编译的 .pyd 模块,它依赖于其他几个 DLL(Python mapscript 和 MapServer),我正在尝试在 Windows 10 上的 IPython 中使用它。设置步骤如下:

到目前为止的调试步骤:

使用新创建的 venv 的 Python 2.7 和 Python 3.6 都会出现同样的问题。这个问题似乎与ipython notebook 可以导入 pyd 模块但 python 解释器不能相反

所以我的问题是 IPython 对 Python 环境做了什么会导致与标准 Python 的差异并导致 ImportError?

标签: pythonipythonimporterror

解决方案


这花了很长时间才找到问题。使用Process Monitor很容易发现任何丢失的 DLL 。然而,在这种情况下,找到了所有相关的 DLL,但其中一个没有我试图导入的 .pyd 文件(或关联的 DLL)使用的函数。

我设法将测试范围缩小到导致错误的 2 个命令 - 直接加载 PYD。

python -c "import _mapscript"
ipython -c "import _mapscript"

我尝试删除/修改 PATH、进出虚拟环境以及 py2 和 py3 并且都产生了相同的错误。

然后我尝试运行 Process Monitor 并比较结果——除了 ipython 为交互式 shell 加载大量额外的 Python 库之外,没有什么特别突出的。

Process Monitor 为每个事件提供了一个方便的 Properties 选项,它还显示为 Process 加载了哪些模块。这些可以排序,然后复制到剪贴板。

加载的模块

我能够比较正常工作的 Python 和损坏的 IPython 进程的输出。IPython 包含来自根 Python 安装 ( C:\Python36\DLLs) 的几个附加 .pyd 文件。我知道我试图加载使用过的 sqlite 的 pyd,这是加载的模块之一(大概是因为 IPython 将所有输入命令存储在 sqlite 数据库中以轻松访问历史记录)。暂时删除 _sqlite3.pyd 文件允许加载模块。

Python DLLs 文件夹优先于 PATH 上的文件夹,因此当前的修复是将 Python DLL 文件夹中的 sqlite3.dll 替换为 MapServer 使用的文件夹,并且一切正常。


推荐阅读