使用pyinstaller构建.exe文件时为什么会出现ImportError错误?

11

我刚刚创建了一个小的GUI程序,它在IPython中编译和运行都很好,但是当我尝试使用pyinstaller将其导出到.exe时,它给了我一个导入错误。我确定问题出在sklearn上,因为当我注释掉sklearn的导入语句后,我的文件可以成功构建并打开。

C:\Users\Chris\Anaconda>C:/Users/Chris/Anaconda/dist/Room_Test.exe
WARNING: file already exists but should not:                            C:\Users\Chris\AppData\Local\Temp\_MEI100402\Include\pyconfig.h
Traceback (most recent call last):
File "<string>", line 9, in <module>
File "C:\Users\Chris\Anaconda\Lib\site-    packages\PyInstaller\loader\pyi_importers.py", line 270, in load_module
exec(bytecode, module.__dict__)
  File "C:\Users\Chris\Anaconda\build\Room_Test\out00-    PYZ.pyz\sklearn.neighbors", line 6, in <module>
  File "C:\Users\Chris\Anaconda\Lib\site-    packages\PyInstaller\loader\pyi_importers.py", line 409, in load_module
    module = imp.load_module(fullname, fp, filename, self._c_ext_tuple)
  File "dist_metrics.pxd", line 48, in init sklearn.neighbors.ball_tree     (sklearn\neighbors\ball_tree.c:35726)
  File "C:\Users\Chris\Anaconda\Lib\site-    packages\PyInstaller\loader\pyi_importers.py", line 409, in load_module
    module = imp.load_module(fullname, fp, filename, self._c_ext_tuple)
  File "dist_metrics.pyx", line 52, in init sklearn.neighbors.dist_metrics     (sklearn\neighbors\dist_metrics.c:25494)
ImportError: No module named typedefs

这不是Python,而是Pyrex C扩展。我想pyinstaller无法自动处理它。 - Dawid Gosławski
4个回答

14

你仍然可以通过将以下内容添加到命令中来使用pyinstaller:

--hidden-import sklearn.neighbors.typedefs

或者在您的 .spec 文件中添加以下内容:

hiddenimports=['cython', 'sklearn', 'sklearn.neighbors.typedefs']

2
我遇到了同样的问题,当我包含 --hidden-import sklearn.neighbors.typedefs 时,我得到了以下错误:RecursionError: maximum recursion depth exceeded - quest
@PankajJoshi - 你可以尝试在规范文件中设置递归限制:https://dev59.com/Y1kT5IYBdhLWcg3wK8dT - mgoldwasser

9

最好使用spec文件导入其他隐藏的库,否则可能会出现问题。我列出了所有Sklearn库,并将其作为隐藏导入添加到spec文件中,如下所示:

  # -*- mode: python -*-

block_cipher = None


a = Analysis(['MyPythonApplication.py'],
             pathex=['..\\ApplicationFolder'],
             binaries=[],
             datas=[],
             hiddenimports=['cython', 'sklearn', 'sklearn.ensemble', 'sklearn.neighbors.typedefs', 'sklearn.neighbors.quad_tree', 'sklearn.tree._utils'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='ExeFileName',             
          debug=False,
          strip=False,
          upx=False,
          console=False )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='ApplicationName')

这对我来说非常有效!只是在我的情况下需要添加'sklearn.pipeline'。 - Hans Bouwmeester

3

我自己解决了!最终使用了py2exe。即使在x64系统上尚不支持将所有模块捆绑到一个.exe文件中,但导入模块要容易得多。但对于我的目的来说,这起作用了。只需将以下行添加到“includes”中:

sklearn.neighbors.typedefs

1

找到这个目录 "E:\Anaconda3\Lib\site-packages\PyInstaller\hooks"。 添加一个文件 "hook-pandas.py",将以下内容写入该文件:

"""
Hook for pandas. 
Suport for pyinstaller error : No module named ‘pandas._libs.tslibs.timedeltas
"""
hiddenimports=[
    #all your previous hidden imports
    'pandas', 'pandas._libs.tslibs.timedeltas',
    'sklearn.neighbors.typedefs'
]

然后使用这个命令:

pyinstaller -F myfile.py --hidden-import sklearn.neighbors.typedefs

然后就可以了!

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