17

我正在尝试通过PyInstaller构建一个 python 脚本。我使用以下命令来配置、生成规范文件和构建:

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

python pyinstaller/Makespec.py --onefile myscript.py
python pyinstaller/Build.py myscript.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 )

这在目录中构建了一个可执行文件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

如果我将此可执行文件移动到实际 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

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

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

4

3 回答 3

8

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

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

hiddenimports=["mysql"],

这应该是结果:

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"],)

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

于 2017-01-26T08:53:11.883 回答
7

当您的代码中有动态导入时,可能会发生此错误。在这种情况下,pyinstaller 不会在 exe 文件中包含这些包。在这种情况下,您可以:

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

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

于 2014-08-27T08:27:51.077 回答
2

只是要加我的 2 美分,因为我今天遇到了同样的问题 - 6 年后:D

对于 Windows:

1) cmd => rightclick => with admin rights
2) Enter in cmd: "pip install pyinstaller"
3) navigate in cmd to the folder of "yourMain.py"
4) Enter in cmd: "pyinstaller --onefile --windowed yourMain.py"

5) If you import other scripts / data in "yourMain.py": 
Manually enter the folder "dist" (gets created - where "yourMain.exe" should be by now), 
and copy your scripts or folder structure there

(e.g. /assets/sounds; /assets/graphics; /scripts; anotherscript.py )

然后我可以通过双击运行exe。

结果很容易。对我有用的是“--onefile”并将我的其他文件添加到“dist”文件夹中。

“--windowed”只是为了在您启动 exe 时不会弹出 python 命令窗口。

于 2017-11-16T19:11:51.327 回答