PyInstaller,规范文件,ImportError:没有名为“blah”的模块
Posted
技术标签:
【中文标题】PyInstaller,规范文件,ImportError:没有名为“blah”的模块【英文标题】:PyInstaller, spec file, ImportError: No module named 'blah' 【发布时间】:2011-11-18 03:58:01 【问题描述】:我正在尝试通过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 docs 中,我看到 --onefile
是我需要/想要的选项,但由于某种原因,并非所有内容都在编译中。
脚本并没有真正包含任何花哨的东西,只是我为 sql 语句编写的一些快速模块,以及解析某些网站。
【问题讨论】:
【参考方案1】:我要加我的 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命令窗口。
【讨论】:
您手动将脚本添加到 dist 文件夹的解决方法终于对我有用。但是,应该还有另一种解决方案... 我正在尝试生成一个安装程序,它将我的 exe 复制到另一个用户系统,因此手动将 .py 文件移动到正确的目录肯定是不切实际的。【参考方案2】:当您的代码中有动态导入时,可能会发生此错误。在这种情况下,pyinstaller 不会在 exe 文件中包含这些包。在这种情况下,您可以:
-
在您的代码中添加这些包的未使用导入
Tell pyinstaller to include it
一个文件选项不会改变运行代码的任何内容。如果你创建 --onefile exe pyinstaller 创建的所有文件都打包到 exe 文件,并在每次运行 exe 时解压到本地 temp。
【讨论】:
【参考方案3】:问题是 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"],)
然后运行 pyinstaller 并将 spec 文件作为参数。
【讨论】:
感谢+1!注意:之后运行 pyinstaller 时,提供 .spec 文件作为参数,而不是 .py 文件! (详细阅读问题,我没有第一次......;)) 这不是真的。 PyInstaller WILL 查找二级导入。然而,有时模块是动态导入的。 (导入是在代码中使用 importlib 完成的)因此 PyInstaller 无法找到该模块。在这些情况下, hidden-import 子句可以解决您的问题。此外,在大多数情况下,您不需要单独运行 Analysis,如果您将 hidden-imports 子句添加到 pyinstaller 命令,它将找到该模块。以上是关于PyInstaller,规范文件,ImportError:没有名为“blah”的模块的主要内容,如果未能解决你的问题,请参考以下文章
如何让 Sass Importer 将文件合并到一个样式表中? [复制]