【问题标题】:No module named when using PyInstaller使用 PyInstaller 时没有命名模块
【发布时间】:2014-11-02 05:11:30
【问题描述】:

我尝试使用 PyInstaller 在 Windows 7 下编译 Python 项目。该项目工作正常,没有问题,但是当我尝试编译它时,结果不起作用。虽然我在编译期间没有收到任何警告,但 build 目录中的 warnmain.txt 文件中有很多警告:warnmain.txt

我不太了解这些警告,例如“没有名为 numpy.pi 的模块”,因为 numpy.pi 不是模块而是一个数字。我从未尝试导入numpy.pi。我确实明确地导入了numpymatplotlib。另外我正在使用 PyQt4。我认为该错误可能与这些库有关。

但是我能够编译一个成功使用 numpy 的简单脚本:

import sys
from PyQt4 import QtGui, QtCore
import numpy as np

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        self.pb = QtGui.QPushButton(str(np.pi), self)

app = QtGui.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())

这里的成功意味着创建的可执行文件实际上显示了所需的输出。然而,还创建了一个warnmain.txt 文件,其中包含与之前完全相同的“警告”。所以我猜想编译我的实际项目并没有取得任何成功的事实与这些警告无关(或至少不仅)。但是还有什么可能是错误呢?编译期间的唯一输出是 'INFO's,并且没有一个是否定语句。

我没有指定一个额外的钩子目录,但我可以从编译输出中读取到使用默认目录的钩子,例如hook-matplotlib 已被执行。我看不到numpy 的任何钩子,我的小示例脚本也看不到,但这个有效。我在我的文件中使用了以下导入(并非全部在相同的文件中,而是在不同的文件中):

import numpy as np
import matplotlib.pyplot as ppl
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
from PyQt4 import QtGui, QtCore
import json
import sys
import numpy # added this one later
import matplotlib # added this one later

由于 PyInstaller 没有给出任何错误/警告,我无法确定问题是否与库有关,或者是否还有其他需要考虑的问题。

【问题讨论】:

  • 当您尝试从命令行启动程序时是否收到错误消息?或者它只是不会启动并且没有打印任何内容(qt 是否将标准输出重定向到其他地方,例如崩溃时关闭的输出窗口?)...进一步我的评论我怀疑你有崩溃(可能来自使用 json 的东西/xml 资源或其他东西(不导入 xxxx)...并且错误消息正在打印到某个 QT 窗口,当您崩溃时该窗口最终会关闭...查看 qt.App 是否有 redirect=False 选项或其他东西来保持标准输出
  • 有趣的是,如果我要执行类似 import numpy.sinh 的操作,我会得到 ImportError: No module named sinh 并且只有当我执行 import numpy.numpy.sinh 时才会得到 ImportError: No module named numpy.sinh 。你检查过PyInstaller finding out what went wrong吗?获取错误/详细导入/调试信息?
  • @JoranBeasley:我只是尝试从 cmd 启动 exe,但没有任何结果,但为了编译,我使用了标志 -w(请参阅 pythonhosted.org/PyInstaller/#options-for-the-executable-output),它阻止 Windows 启动任何控制台输入输出。如果我在没有-w 的情况下进行编译,我将无法获得图形用户界面。但是,从解释器调用时程序运行良好,所以我不认为这是内部错误。 @ssnobody:我知道那个链接,但它没有给我带来任何好处。 import numpy.sinh 将无法工作,因为 sinh 不是模块。
  • @JoranBeasley:我必须纠正自己,似乎可以在没有-w 的情况下编译并获得 GUI。但是,如果我这样做,我会得到一个控制台,在那里我可以在很短的时间内看到(实际阅读时间很短)那里写了一些东西,但随后应用程序终止了。 GUI 不出现。我尝试以某种方式将此标准输出保存到文件中,以便我可以实际读取它。
  • @JoranBeasley 谢谢伙计,你的建议是正确的!实际上缺少一些库(我通过导入它们来修复它们,请参阅我编辑的问题)。如果您没有发布答案,我将简短地总结一下。谢谢!

标签: python numpy matplotlib pyqt4 pyinstaller


【解决方案1】:

no module named FileDialog 也有类似的问题。发现使用 3.2 版,我可以使用

pyinstaller --hidden-import FileDialog ...

而不是修改我的主脚本。

【讨论】:

  • 哇,这很有帮助,tnx。尽管我必须通过在同一文件夹中创建 __init__.py 来使我的主脚本文件夹成为 python 包。否则会发生奇怪的事情,具体取决于运行可执行文件的位置。从相对导入失败到导入 serial 失败的任何事情。
  • 我不得不多次使用这个--hidden-import 选项来修复在尝试运行已编译的 exe 时出现的 ModuleNotFound 错误。使用nacl 模块时,缺少的模块是_cffi_backendnacl
【解决方案2】:

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

无需更改您的 python 脚本中的任何内容。您可以直接将缺少的导入添加到 spec 文件。 只需更改以下行:

hiddenimports=[],

hiddenimports=["Tkinter", "FileDialog"],

【讨论】:

    【解决方案3】:

    问题是 matplotlib 的一些运行时依赖项。因此,在运行程序时编译很好,引发了一些错误。因为终端立即关闭,我没有意识到这一点。将stdoutstderr 重定向到一个文件后,我可以看到我错过了库TkinterFileDialog。在 main 顶部添加两个imports 解决了这个问题。

    【讨论】:

    • 这是我使用的重定向命令:myprogram.exe 1> errors.txt 2>&1 --- 我得到了和你一样的结果...我也缺少 Tkinter 和 FileDialog 模块: ) 谢谢,非常感谢。
    • 那么是 PyInstaller 不接受二级导入的问题吗?或者这不是一个带有 setup.py 的项目?
    • 是的。如果你导入一个模块,而这个模块自己导入其他模块,那么 PyInstaller 显然不会实现那些二级导入。
    【解决方案4】:

    如果您收到ModuleNotFoundError: No module named ... 错误并且您:

    • 从主脚本以外的目录调用 PyInstaller
    • 在脚本中使用相对导入

    那么您的可执行文件可能无法找到相关导入。

    这可以通过以下方式解决:

    • 从与主脚本相同的目录调用 PyInstaller

    • 或删除任何 __init__.py 文件(在 Python 3.3+ 中不需要空的 __init__.py 文件)

    • 或者使用 PyInstaller 的 paths 标志来指定 path to search for imports。例如。如果您从父文件夹调用 PyInstaller 到您的主脚本,并且您的脚本位于 subfolder,则调用 PyInstaller:

      pyinstaller --paths=subfolder subfolder/script.py.

    【讨论】:

    • 您好,感谢您的回答,尤其是--paths 部分。谢谢你
    【解决方案5】:

    我遇到了同样的问题,以下解决方案对我有用:

    1. 我首先删除了我正在工作的虚拟环境。
    2. 使用pip重新安装了所有模块(注意:这次我没有创建任何虚拟环境)。
    3. 然后我调用了 pyinstaller
    4. 之后创建的.exe文件运行顺利,没有任何模块导入错误。

    【讨论】:

    • 和你一样,我发现 pyinstaller 找不到我用Poetry 安装的模块。但是,我可以使用安装在使用 python3 -m venv venv 创建的“venv”虚拟环境中的模块
    • 这个对我有用 非常感谢。
    【解决方案6】:

    如果问题是因为您使用的是 PyQt4 而不需要 Tkinter 和朋友,那么最好完全避免加载 Tkinter 等。查看 /etc/matplotlibrc 并将默认值更改为 PyQt4,请参阅下面的“修改”行:

    #### CONFIGURATION BEGINS HERE
    
    # The default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
    # CocoaAgg MacOSX Qt4Agg Qt5Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG
    # Template.
    # You can also deploy your own backend outside of matplotlib by
    # referring to the module name (which must be in the PYTHONPATH) as
    # 'module://my_backend'.
    
    #modified 
    #backend      : TkAgg
    backend      : Qt4Agg
    
    
    # If you are using the Qt4Agg backend, you can choose here
    # to use the PyQt4 bindings or the newer PySide bindings to
    # the underlying Qt4 toolkit.
    
    #modified 
    #backend.qt4 : PyQt4        # PyQt4 | PySide
    backend.qt4 : PyQt4        # PyQt4 | PySide
    

    【讨论】:

      【解决方案7】:

      我在 pyinstaller 3.0 和 weblib 上遇到了同样的问题。主要导入它没有帮助。

      升级到 3.1 并删除所有构建文件有所帮助。

      pip install --upgrade pyinstaller
      

      【讨论】:

        【解决方案8】:

        可能不是一个好习惯,但在我的项目中使用的原始环境中安装 pyinstaller(而不是单独的 venv)有助于解决 ModuleNotFoundError

        【讨论】:

          【解决方案9】:

          我在 PySimpleGUI 上遇到过类似的问题。 问题是,pyinstaller 安装在不同的目录中。 解决方案(为我解决):只需将 pyinstaller 安装在文件所在的同一目录中(要转换为 exe)

          【讨论】:

            猜你喜欢
            • 2021-11-23
            • 2017-11-28
            • 1970-01-01
            • 1970-01-01
            • 2019-06-17
            • 1970-01-01
            • 2018-07-01
            • 2016-09-03
            • 2020-08-17
            相关资源
            最近更新 更多