使用py2exe时出现IndexError: tuple index out of range错误

109

我目前正在尝试使用py2exe制作可执行文件。 我使用的是Python 3.6版本。 我正在使用的脚本导入了openpyxlpptx并且在Pycharm中或者通过命令窗口运行脚本时可以正常运行。

但是编译后的输出出现了以下错误:

IndexError: tuple index out of range

以下是cmd的输出结果:

C:\Python36>python setup.py py2exe
running py2exe
Traceback (most recent call last):
  File "setup.py", line 4, in <module>
    setup(console=['Storybookmaker.py'])
  File "C:\Python36\lib\distutils\core.py", line 148, in setup
    dist.run_commands()
  File "C:\Python36\lib\distutils\dist.py", line 955, in run_commands
    self.run_command(cmd)
  File "C:\Python36\lib\distutils\dist.py", line 974, in run_command
    cmd_obj.run()
  File "C:\Python36\lib\site-packages\py2exe\distutils_buildexe.py", line 188, in run
    self._run()
  File "C:\Python36\lib\site-packages\py2exe\distutils_buildexe.py", line 267, in _run
    builder.analyze()
  File "C:\Python36\lib\site-packages\py2exe\runtime.py", line 160, in analyze
    self.mf.import_hook(modname)
  File "C:\Python36\lib\site-packages\py2exe\mf3.py", line 120, in import_hook
    module = self._gcd_import(name)
  File "C:\Python36\lib\site-packages\py2exe\mf3.py", line 274, in _gcd_import
    return self._find_and_load(name)
  File "C:\Python36\lib\site-packages\py2exe\mf3.py", line 357, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Python36\lib\site-packages\py2exe\mf3.py", line 388, in _scan_code
    for what, args in self._scan_opcodes(code):
  File "C:\Python36\lib\site-packages\py2exe\mf3.py", line 417, in _scan_opcodes
    yield "store", (names[oparg],)
IndexError: tuple index out of range

C:\Python36>
什么导致了IndexError错误?
编辑:这是setup.py文件:
from distutils.core import setup
import py2exe

setup(console=['Storybookmaker.py'])

2
你能给我们展示一下你的 setup.py 文件吗?问题出在那里,而不是 py2exe,因为它运行良好。 - Jean-François Fabre
1
嗨,Jean-Francois,我已经在原始帖子中添加了文件。提前致谢! - Dennis
1
Storybookmaker.py文件是否与setup.py文件在同一目录下?您可以尝试使用setup(console=[os.path.join(os.path.dirname(__file__,'Storybookmaker.py')])来确保定位到该文件。 - Jean-François Fabre
1
@Jean-FrancoisFabre setup.py和Storybookmaker.py都在C:\Python36文件夹中,所以这应该不是问题,但我还是按照您的代码尝试了一下。结果出现了相同的IndexError错误。您还有什么其他想法吗? - Dennis
@Dennis:py2exe已经回来了。请查看我的更新答案(如果它解决了你的问题,请给个赞)。 - ShadowRanger
6个回答

101

更新(2020年11月17日):py2exe得以继续使用!!!

显然,我一年前的悲观情绪是不必要的(请参见原帖底部的“更新”)。py2exe在2020年10月和11月发布了新版本,支持3.5-3.8的0.10.0.2版本,并在0.10.1.0中添加了对3.9的支持(停止支持3.4及更早版本)。只要您升级到适当的py2exe版本(0.10及更高版本),就不会出现这个问题。

最新更新(2022-11-09):看起来py2exe现在正在与最新版本的CPython保持同步(例如,他们发布了0.13.0.0,一个兼容3.11的py2exe,在CPython 3.11.0本身发布两周内),因此看起来您可以依赖继续支持。他们似乎为任何给定的版本支持4-5个小版本的CPython(第一个支持3.9的版本放弃了对3.4及更早版本的支持,而添加对3.11支持的最新版本放弃了3.7的支持)。

py2exe 0.10发布前的原始答案

Python 3.6 完全重新设计了CPython的字节码(它现在不再是“字节”码,而是一个wordcode,在这个wordcode中,所有操作码都是两个字节宽而不是1-3)。

你看到的错误发生在py2exe操作码解析代码中,在最近发布的py2exe版本中(仅声称支持3.3和3.4),它不能可能具有对新的wordcode操作码的知识或支持;在上次更新py2exe时,它们甚至还没有被构想出来。即使从版本到版本中字节码也经常以微小的方式改变,这可能会破坏甚至Python 3.5(只给出了明确的3.3和3.4支持),但是保证会失败100%的是3.6。

更新:截至2019年11月,距离最后一次py2exe发布已经过去五年以上,在2020年初(当Python 2的支持完全终止时),它将无法在任何支持的Python版本上运行(3.4已经不再得到支持)。我认为可以肯定地说该项目已被放弃;请寻找其他选项,例如cx_FreezePyInstaller


4
那难道没有其他选择吗? - Ghasem
@AlexJolig:有一些,但我还没有检查它们是否都兼容Python 3.6。我知道PyInstaller和cx_Freeze;可能还有其他的。 - ShadowRanger
8
我已经测试了cx_freeze,它兼容Python3.6,但无法创建单个的exe文件。而Pyinstaller的问题在于,你无法通过x64操作系统创建x86的exe文件。 - Ghasem
感谢提供这个信息。我必须说我有点惊讶,因为这似乎并没有在前面做好记录。即使是 py2exe 的描述也仅仅说“支持 Python 3.3 及其以后版本”。当然,回过头来看,期望这么老的东西能够工作可能有点幼稚,但当你是这个领域的新手时,已经有足够的新手困扰需要解决了。 - fostandy
@fostandy:请查看更新后的答案。看起来他们终于将其更新到最新版本(停止支持3.4及更早版本,增加对3.5至3.9的支持)。 - ShadowRanger
版本0.10.1.0已停止支持3.5。 - recurseuntilfor

41

更新(2021年11月3日):正如@ShadowRanger在他的更新中所说,py2exe仍在维护中。此外,版本0.10.1.0已停止对python 3.5或更低版本提供支持,可以使用PyInstaller或cx_Freeze作为替代方案。


原始回答:

我使用的解决方案是使用PyInstaller作为替代方案,因为Py2Exe在python 3.4停止开发,并且无法与更新的版本一起使用。

C:/>pip install pyinstaller
C:/>pyinstaller yourprogram.py

这将创建一个名为dist的子目录,其中yourprogram.exe包含在名为yourprogram的文件夹中。

使用-F将所有生成的文件放入一个可执行文件中。

C:/>pyinstaller -F yourprogram

如果您想为GUI删除控制台显示,可以使用-w选项。

C:/>pyinstaller -w yourprogram.py

将所有内容集成在一起。

C:/>pyinstaller -w -F yourprogram.py

关于PyInstaller的更多信息,请点击这里

Python版本为3.7.3。


2
如果我在其他计算机上运行该程序,会出现“找不到模块”的错误提示。 - yarin Cohen
感谢您提供有关PyInstaller的解决方案。我成功地使用minggw64 python3.8.2版本和Windows 10上的GTK创建了一个独立项目:gi、gtk、dlls等所有文件都在dist文件夹中,只需在minggw64 shell中使用简单的"$ pyinstaller yourprogram"命令即可。 PyInstaller + Cython看起来是一个不错的组合。 - jerome

10

我曾经遇到同样的问题,作为解决方法,我使用了cx_freeze。我的应用程序基于wxPython、Windows 10、Python 3.6、cx_freeze 5.5.1。

这是我使用的设置文件,我在dist文件夹中得到了msi文件。

#setup.py
import sys, os
from cx_Freeze import setup, Executable

__version__ = "1.1.0"

include_files = ['logging.ini', 'config.ini', 'running.png']
excludes = ["tkinter"]
packages = ["os", "idna", "requests","json","base64","pyodbc"]

setup(
    name = "appname",
    description='App Description',
    version=__version__,
    options = {"build_exe": {
    'packages': packages,
    'include_files': include_files,
    'excludes': excludes,
    'include_msvcr': True,
}},
executables = [Executable("b2b_conn.py",base="Win32GUI")]
)`

然后执行python setup.py bdist_msi


4
和你一样,我也使用了cx_freeze来创建可执行文件,因为它与我的Python版本兼容且易于使用。感谢您分享设置文件,以便其他人可以将其用作示例。 - Dennis
如果我有 from PyQt5 import QtGui,我该如何在 packages 中输入它?只输入 PyQt5 还是只输入 QtGui 还是两者都输入? - Hrvoje T
Hrvoje T,我已经包含了整个PyQt5 - Taras Mykhalchuk

7

在我的 Python 3.7 上运行正常。 - adejones

7

我尝试了一个解决方法,安装了Python 3.4.3:

C:\socket> c:\Python34\python.exe setup.py py2exe

1)进入您的脚本文件夹

2)禁用任何杀毒软件(这可能很奇怪,但是在其他SO问题中被发现)

3)通过其绝对路径调用Python 3.4.3解释器,在我的情况下,我已安装在:

C:\Python34

4) 执行该命令。

C:\Python34\python.exe setup.py py2exe

我尝试使用Python 3.5做同样的事情,但在安装py2exe时卡住了,因为pip需要更新到新版本,我遇到了一个错误。 您正在使用pip版本8.1.1,但版本9.0.1可用。 您应该考虑通过“python -m pip install --upgrade pip”命令进行升级。 当我尝试升级pip时,我得到了相同的错误! - Dennis
据我所见,你有两个选择:
  1. 尝试使用Python 3.4.3版本,我已经测试过了。
  2. 确认你使用的是哪个版本的python,在控制台输入'python'命令,看看它显示的是哪个版本。可能存在两个版本的python,需要指定你想要更新的版本。
- Ricardo Martínez
顺便说一句,@Dennis - Ricardo Martínez
Martinez的版本现在显示为3.5而不是3.6。我指定了3.5的路径,pip 8.1.1仅安装在3.5上,因为3.6已经有9.0.1了。我会尝试您的建议使用多个版本。 - Dennis
Martinez 感谢您的帮助。最终我决定坚持使用我的 Python 3.6 版本。我尝试了 cx_freeze 将我的代码编译成 .exe 文件,效果非常好! - Dennis
显示剩余2条评论

0

目前最新的 Python 版本是 3.8,而 py2exe 可以使用到 Python 3.4。而 pyinstaller 可以使用到 Python 3.7。使用 pyinstaller 的命令行选项(例如 --onefile 以创建独立的可执行文件)比将选项编码到 py2exe 的 setup.py 文件中更容易...特别是因为适用于 Python 2 的 setup.py 文件不适用于 Python 3。另一个有用的 pyinstaller 选项是 --noconsole,可以使可执行文件作为后台进程启动。

因此,一个无时限的解决方案是使用 Python 模块 virtualenv。然后,您可以创建可执行文件,而无需卸载当前 Python 版本及其所有模块,以替换为旧版本。

C:\Users\jf>pip install virtualenv
C:\Users\jf>python -m virtualenv box37 -p c:\users\jf\python37\python.exe
C:\Users\jf>C:\Users\jf\box37\Scripts\activate
(box37) C:\Users\jf>
(box37) C:\Users\jf>pip install pyinstaller
(box37) C:\Users\jf>pyinstaller --onefile test.py
(box37) C:\Users\jf>deactivate
C:\Users\jf>

命令行选项-p c:\path\to\target\python\interpreter是区分大小写的!对于pyinstaller,请使用您下载Python-3.7的路径(对于py2exe,请使用3.4的路径)。

创建虚拟环境时,会在工作目录中生成一个以您指定名称(例如box37)命名的目录。在此目录中执行脚本\Script\activate可进入虚拟环境 - 注意在我的提示符之前出现了(box37)。

在Python虚拟环境中,使用pip安装模块,这些模块在Python外部不可访问 - 请注意它有自己的\Lib\site-packages目录。因此,virtualenv成为完美的测试设置模块 - 如果出错,只需删除(例如box37)目录即可。

下载Python 3.7,Windows x86-64可执行安装程序。下载Python 3.4,Windows x86-64 MSI安装程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接