仅在使用IPython时使用ImportError

时间:2018-10-29 10:00:08

标签: python ipython importerror

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

  • 创建了一个新的虚拟环境
  • 将mapscript安装到环境中
  • 将PATH设置为包含包含MapServer DLL的文件夹
  • 使用标准venv Python运行时,“导入映射脚本”可以正常工作
  • 启动ipython并运行“导入映射脚本”时,出现以下错误:ImportError: DLL load failed: The specified procedure could not be found.

到目前为止的调试步骤:

  • sys.executable在两种情况下都是相同的(venv Python和venv IPython)
  • os.environ [“ PATH”]相同
  • ipython中的
  • sys.path在IPython中最后有几个额外的路径-C:\Users\user\.ipython和'c:\ virtualenvs \ mapscript-jupyter3 \ lib \ site-packages \ IPython \ extensions',但在其他方面相同。删除这些路径不会更改错误。
  • 我尝试使用Process Monitor查找丢失的DLL,但似乎都找到了。

在具有新创建的venv的Python 2.7和Python 3.6中,都会发生相同的问题。 问题似乎与ipython notebook can import a pyd module but the python interpter can't

相反

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

1 个答案:

答案 0 :(得分:0)

这花费了相当长的时间才能找到问题。通过使用Process Monitor,很容易发现所有丢失的DLL。但是,在这种情况下,找到了所有依赖的DLL,但是其中一个没有我要导入的.pyd文件(或关联的DLL)使用的功能。

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

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

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

然后,我尝试运行Process Monitor并比较结果-除了ipython之外,没有其他功能可以为交互式shell加载很多其他Python库。

Process Monitor对于每个事件都包括一个方便的Properties选项,该选项还显示了为Process加载了哪些模块。可以对它们进行排序,然后将其复制到剪贴板。

Loaded Modules

我能够比较正在运行的Python和损坏的IPython进程的输出。 IPython包括来自Python根安装目录(C:\Python36\DLLs)的几个其他.pyd文件。我知道我正在尝试加载使用的sqlite的pyd,而这是已加载的模块之一(大概是因为IPython将所有输入命令存储在sqlite数据库中以便轻松访问历史记录)。临时删除_sqlite3.pyd文件可以加载该模块。

Python DLLs文件夹的优先级高于PATH上的文件夹,因此当前的解决方法是用MapServer使用的DLL替换Python DLL文件夹中的sqlite3.dll,并且所有文件都可以正常工作。