PyInstaller,spec文件,ImportError:没有名为'blah'的模块

Cma*_*mag 14 python mysql pyinstaller importerror

我试图通过PyInstaller构建一个python脚本.我使用以下命令来配置,生成spec文件和构建:

wget pyinstaller.zip, extracted it, python Configure.py, etc, then:

python pyinstaller/Makespec.py --onefile myscript.py
python pyinstaller/Build.py myscript.spec 
Run Code Online (Sandbox Code Playgroud)

这是它生成的spec文件:

# -*- mode: python -*-
a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), 'icinga.py'],
             pathex=['/home/user/projects/icinga_python/releases/v2.1'])
pyz = PYZ(a.pure)
exe = EXE( pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name=os.path.join('dist', 'myscript'),
          debug=False,
          strip=False,
          upx=True,
          console=1 )
Run Code Online (Sandbox Code Playgroud)

这在dist/目录中构建了一个可执行文件.尝试运行此文件时,我得到以下内容:

Traceback (most recent call last):
  File "<string>", line 12, in <module>
  File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 455, in importHook
    raise ImportError, "No module named %s" % fqname
ImportError: No module named mysql
Run Code Online (Sandbox Code Playgroud)

如果我将此可执行文件移动到实际Python代码的目录中,它会给出不同的结果:

Traceback (most recent call last):
  File "<string>", line 12, in <module>
  File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 436, in importHook
    mod = _self_doimport(nm, ctx, fqname)
  File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 521, in doimport
    exec co in mod.__dict__
  File "CLUSTER/mysql/icingasql.py", line 13, in <module>
    import urllib2
  File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 455, in importHook
    raise ImportError, "No module named %s" % fqname
ImportError: No module named urllib2
Run Code Online (Sandbox Code Playgroud)

在... pyinstaller文档中,我看到这--onefile是我需要/想要的选项,但由于某种原因,并非所有内容都被编译.

这个脚本并没有真正包含任何花哨的内容,只是我为sql语句编写的一些快速模块,以及解析某些网站.

use*_*007 7

问题是 pyinstaller 不会看到二级导入。因此,如果您导入模块A, pyinstaller 会看到这一点。但是在A 中导入的任何附加模块都不会被看到。

无需更改 Python 脚本中的任何内容。您可以直接将缺少的导入添加到规范文件中。只需添加以下内容a = Analysis(...)

hiddenimports=["mysql"],
Run Code Online (Sandbox Code Playgroud)

结果应该是这样:

a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), 'icinga.py'],
         pathex=['/home/user/projects/icinga_python/releases/v2.1'], hiddenimports=["mysql"],)
Run Code Online (Sandbox Code Playgroud)

之后,以规范文件作为参数运行 pyinstaller。

  • 这不是真的。PyInstaller ***WILL*** 找到二级导入。然而,有时模块是动态导入的。(导入是在带有 importlib 的代码中完成的),因此 PyInstaller 无法找到该模块。在这些情况下,hidden-import 子句可以解决您的问题。此外,在大多数情况下,您不需要单独运行 Analysis,如果将 hidden-imports 子句添加到 pyinstaller 命令,它将找到该模块。 (2认同)

gko*_*jan 5

在代码中进行动态导入时,此错误可能会发生.在这种情况下,pyinstaller不会在exe文件中包含这些包.在这种情况下,你可以:

  1. 在代码中添加这些包的未使用导入
  2. 告诉pyinstaller包含它

一个文件选项在运行代码时不会改变任何内容.如果您创建--onefile exe,则由pyinstaller创建的所有文件都打包到exe文件,并在每次运行exe时解压缩到本地temp.