Pyinstaller exe转换失败-使用lightgbm和sklearn

时间:2019-04-08 06:15:32

标签: python python-3.x scikit-learn pyinstaller lightgbm

我正在尝试使用pyinstaller规范将我的代码转换为exe。 Pyinstaller最初失败的原因如下:

main__.PyInstallerImportError: Failed to load dynlib/dll 
'C:\\Users\\...\\lightgbm\\../compile\\lib_lightgbm.dll'. Most probably this 
dynlib/dll was not found when the application was frozen.

我尝试通过将以下行添加到规范中的pathex列表中来纠正它:

'myenv\\lib\\site-packages\\lightgbm'

注意:myenv是为此项目创建的我的virtualenv。

这导致sklearn的ImportError。我将sklearn添加到隐藏的导入中。这是我最后的说明:

# -*- mode: python -*-
import sys
sys.setrecursionlimit(5000)

block_cipher = None


a = Analysis(['myscript.py'],
             pathex=['C:\\project_folder', 'myenv\\lib\\site-packages\\lightgbm'],
             binaries=[],
             datas=[('lib_lightgbm.dll', '.')],
             hiddenimports=['cython', 'sklearn', 'sklearn.feature_extraction','sklearn.pipeline', '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,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='myscript',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='myscript')

这导致我发现很奇怪的错误:

File "myenv\lib\site-packages\lightgbm\sklearn.py", line 9, in <module>
ImportError: attempted relative import with no known parent package
[12692] Failed to execute script myscript

我不知道为什么要在lightgbm中搜索sklearn.py? lightgbm中有sklearn.py,但是我不确定如何解决此错误。另外,在dist / myscript文件夹中没有sklearn文件夹。理想情况下应该已经存在。我尝试手动复制sklearn文件夹,尽管据怀疑,它没有任何区别。有人可以让我知道规格文件在哪里吗?

1 个答案:

答案 0 :(得分:0)

让我们回到您遇到的第一个错误。该错误表明在冻结应用程序时未看到lib_lightgbm.dll

假设您从Windows cmd.exe运行pyinstaller,则可以通过将lightgbm的钩子传递给pyinstaller来解决此问题,以便它知道从何处获取它,例如

pyinstaller --additional-hooks-dir dir_with_lightgbm_hook --hidden-import lightgbm myscript.py

挂钩的名称应为hook-lightgbm.py,对于其内容,您可以在这里查看:https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/hooks/hook-numpy.py,它应该类似。只需确保将库添加到二进制列表,即

binaries.append((os.path.join(os.path.dirname(
get_module_file_attribute('lightgbm')), "lib_lightgbm.dll"), "lightgbm"))

第二个"lightgbm"参数是.dll相对于分发目录的复制位置,因此,在您的情况下,它应以dist\myscript\lightgbm\lib_lightgbm.dll结尾。

注意:通过钩子添加lib_lightgbm.dll将使pyinstaller将其依赖项添加到发行版中,因此比手动复制它更好。 >

第二条记录:将分发包复制到另一台计算机时,您可能需要安装该库使用的适当的Visual Studio可再发行组件(例如VS 2015可再发行组件)。

编辑:忘了说,如果您这样做,可以删除添加到pathex的路径。