PyInstaller,规范文件,ImportError:没有名为“blah”的模块
- 2024-12-27 08:47:00
- admin 原创
- 120
问题描述:
我正在尝试通过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
这是它生成的规范文件:
# -*- 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 语句编写的一些快速模块以及解析某些网站。
解决方案 1:
当您的代码中有动态导入时,可能会发生此错误。在这种情况下,pyinstaller不会在exe文件中包括这些包。在这种情况下,您可以:
在代码中添加这些未使用的包的导入
告诉 pyinstaller 将其包含
一个文件选项不会在运行代码时改变任何内容。如果您创建 --onefile exe,则 pyinstaller 创建的所有文件都将打包到 exe 文件中,并在每次运行 exe 时解压到本地临时文件中。
解决方案 2:
问题是 pyinstaller 看不到第二级导入。因此,如果您导入模块A ,pyinstaller 会看到它。但在A中导入的任何其他模块都不会被看到。
无需更改 Python 脚本中的任何内容。您可以直接将缺少的导入添加到spec 文件。只需添加以下内容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"],)
之后,使用 spec 文件作为参数运行 pyinstaller。
解决方案 3:
我只是想说说我的看法,因为今天我遇到了同样的问题——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 命令窗口。