【问题标题】:py2exe and numpy not getting alongpy2exe 和 numpy 相处不来
【发布时间】:2011-02-04 06:20:32
【问题描述】:

我正在尝试使用 py2exe-0.6.9.win32 来包装我用 Python2.6.5 编写的应用程序,并使用以下具有相关下载文件名的对象库:

matplotlib-0.99.3.win32

numpy-1.4.1-win32

scipy-0.8.0b1-win32

wxPython2.8-win32-unicode-2.8.11.0

当我尝试启动生成的 .exe 文件时收到错误消息。目前,该错误消息与 numpy 有关,尽管在此之前我得到了一些与 matplot lib 数据文件未加载相关的内容,因此阻止了我的 exe 文件的启动。

我不是发布一英里的代码和所有错误消息,而是发布一个更一般的问题:谁能告诉我一些说明,让所有这些对象库和版本一起使用 py2exe 创建一个运行 exe 文件?

我一直在阅读有关该主题的 google 搜索结果,但这似乎是一场疯狂的追逐,因为每个人都在使用不同版本的不同事物。如果有影响,我可以更改其中一些对象库的一些版本,但我已经在这个信号处理应用程序中编写了 5,000 行代码,我宁愿不必重新编写所有代码,如果可能。


编辑:

这是我在一个名为 GUIdiagnostics.py 的文件中的代码的简化版本,用于测试我的 py2exe 脚本是否能够导入我在实际应用程序中需要的所有库:

import time
import wxversion
import wx
import csv
import os
import pylab as p
from scipy import stats
import math
from matplotlib import *
from numpy import *
from pylab import *
import scipy.signal as signal
import scipy.optimize
import Tkinter

ID_EXIT = 130

class MainWindow(wx.Frame):
    def __init__(self, parent,id,title):
        wx.Frame.__init__(self,parent,wx.ID_ANY,title, size = (500,500), style =     wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)

        # A button
        self.button =wx.Button(self, label="Click Here", pos=(160, 120))
        self.Bind(wx.EVT_BUTTON,self.OnClick,self.button)

        # the combobox Control
        self.sampleList = ['first','second','third']
        self.lblhear = wx.StaticText(self, label="Choose TestID to filter:", pos=(20, 75))
        self.edithear = wx.ComboBox(self, pos=(160, 75), size=(95, -1),     choices=self.sampleList, style=wx.CB_DROPDOWN)

        # the progress bar
        self.progressMax = 3
        self.count = 0
        self.newStep='step '+str(self.count)
        self.dialog = None

        #-------Setting up the menu.
        # create a new instance of the wx.Menu() object
        filemenu = wx.Menu()

        # enables user to exit the program gracefully
        filemenu.Append(ID_EXIT, "E&xit", "Terminate the program")

        #------- Creating the menu.
        # create a new instance of the wx.MenuBar() object
        menubar = wx.MenuBar()
        # add our filemenu as the first thing on this menu bar
        menubar.Append(filemenu,"&File")
        # set the menubar we just created as the MenuBar for this frame
        self.SetMenuBar(menubar)
        #----- Setting menu event handler
        wx.EVT_MENU(self,ID_EXIT,self.OnExit)

        self.Show(True)

    def OnExit(self,event):
        self.Close(True)

    def OnClick(self,event):
        try:
            if not self.dialog:
                self.dialog = wx.ProgressDialog("Progress in processing your data.", self.newStep,
                                            self.progressMax,
                                            style=wx.PD_CAN_ABORT
                                            | wx.PD_APP_MODAL
                                            | wx.PD_SMOOTH)
            self.count += 1
            self.newStep='Start'
            (keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
            TestID = self.edithear.GetValue()

            self.count += 1
            self.newStep='Continue.'
            (keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
            myObject=myClass(TestID)
            print myObject.description

            self.count += 1
            self.newStep='Finished.'
            (keepGoing, skip) = self.dialog.Update(self.count,self.newStep)

            self.count = 0

            self.dialog.Destroy()

        except:
            self.dialog.Destroy()
            import sys, traceback
            xc = traceback.format_exception(*sys.exc_info())
            d = wx.MessageDialog( self, ''.join(xc),"Error",wx.OK)
            d.ShowModal() # Show it
            d.Destroy() #finally destroy it when finished

class myClass():
    def __init__(self,TestID):
        self.description = 'The variable name is:  '+str(TestID)+'. '

app = wx.PySimpleApp()
frame = MainWindow(None,-1,"My GUI")
app.MainLoop()

这里是 setup.py 的代码,这是包含我的 py2exe 代码的文件:

from distutils.core import setup
import py2exe

# Remove the build folder, a bit slower but ensures that build contains the latest
import shutil
shutil.rmtree("build", ignore_errors=True)

# my setup.py is based on one generated with gui2exe, so data_files is done a bit differently
data_files = []
includes = []
excludes = ['_gtkagg', '_tkagg', 'bsddb', 'curses', 'pywin.debugger',
        'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl',
        'Tkconstants', 'Tkinter', 'pydoc', 'doctest', 'test', 'sqlite3'
        ]
packages = ['pytz']
dll_excludes = ['libgdk-win32-2.0-0.dll', 'libgobject-2.0-0.dll', 'tcl84.dll',
            'tk84.dll']
icon_resources = []
bitmap_resources = []
other_resources = []

# add the mpl mpl-data folder and rc file
import matplotlib as mpl
data_files += mpl.get_py2exe_datafiles()

setup(
    windows=['GUIdiagnostics.py'],
                      # compressed and optimize reduce the size
    options = {"py2exe": {"compressed": 2, 
                      "optimize": 2,
                      "includes": includes,
                      "excludes": excludes,
                      "packages": packages,
                      "dll_excludes": dll_excludes,
                      # using 2 to reduce number of files in dist folder
                      # using 1 is not recommended as it often does not work
                      "bundle_files": 2,
                      "dist_dir": 'dist',
                      "xref": False,
                      "skip_archive": False,
                      "ascii": False,
                      "custom_boot_script": '',
                     }
          },

    # using zipfile to reduce number of files in dist
    zipfile = r'lib\library.zip',

    data_files=data_files
)

我按照以下链接在 windows (cmd.exe) 的命令行界面中键入以下行来运行此代码:

setup.py py2exe

Py2exe 然后运行,但是当我尝试启动生成的 exe 文件时,它会创建一个包含以下消息的日志文件:

Traceback (most recent call last):
  File "setup.py", line 6, in <module>
  File "zipextimporter.pyo", line 82, in load_module
  File "pylab.pyo", line 1, in <module>
  File "zipextimporter.pyo", line 82, in load_module
  File "matplotlib\pylab.pyo", line 206, in <module>
  File "zipextimporter.pyo", line 82, in load_module
  File "matplotlib\mpl.pyo", line 3, in <module>
  File "zipextimporter.pyo", line 82, in load_module
  File "matplotlib\axes.pyo", line 14, in <module>
  File "zipextimporter.pyo", line 82, in load_module
  File "matplotlib\collections.pyo", line 21, in <module>
  File "zipextimporter.pyo", line 82, in load_module
  File "matplotlib\backend_bases.pyo", line 32, in <module>
  File "zipextimporter.pyo", line 82, in load_module
  File "matplotlib\widgets.pyo", line 12, in <module>
  File "zipextimporter.pyo", line 82, in load_module
  File "matplotlib\mlab.pyo", line 388, in <module>
TypeError: unsupported operand type(s) for %: 'NoneType' and 'dict'

谁能告诉我如何编辑 setup.py 以便 py2exe 可以创建一个运行 numpy、scipy、matplotlib 等的可用可执行文件?


第二次编辑:

好的。我今天再次尝试了 RC 的建议,因为我对此有了新的想法,并且遇到了同样的错误,但我将其包括在下面。这是我按照模板创建的名为 cxsetup.py 的文件的代码:http://cx-freeze.sourceforge.net/cx_Freeze.html

from cx_Freeze import setup, Executable

setup(
        name = "Potark",
        version = "0.1",
        description = "My application.",
        executables = [Executable("Potark-ICG.py")])

不幸的是,在命令行 ( cmd.exe ) 中使用以下命令运行它:

python cxsetup.py build

在命令行中生成以下错误:

ImportError: No module named cx_Freeze

命令行中的目录是我的应用程序的目录,它位于桌面的子文件夹中。这与 python 应用程序的目录不同,但我认为 cmd.exe 可以解决这个问题,因为 python 可以解决它。 我错了吗?作为测试,我在 cxsetup.py 的第一行添加了以下代码行:

import matplotlib

但这产生了几乎相同的错误:

ImportError: No module named matplotlib

我试图保持这个线程的重点和简短,但它变得有点长。 谁能帮我解决这个问题?我不想做所有切换到 cx_freeze 的工作,却发现它不能与 numpy、matplotlib、scipy 等一起工作。

【问题讨论】:

  • 也许你可以试试 cxfreeze 看看它是否有助于创建一个可以工作的 exe
  • 谢谢。我试过了,但是我从 cxfreeze 收到了不同的错误消息,我更愿意让这个线程保持专注,这样我就不会因为太多的代码或太多的错误消息而混淆人们。编程的这个方面对我来说是新的。
  • 没问题,值得一试。
  • 我今天再次尝试了您的建议,并收到了上面第二次编辑中描述的错误消息。我真的很感激一些建议。
  • 我并不是要混淆任何人切换到 cx_freeze。我很高兴在 py2exe 中做到这一点。如上所述,我只想要与 numpy、scipy、matplotlib 等一起使用的东西。我有一种感觉,如果有人不建议一个简单的解决方案,这可能会变得很棘手。我担心 cx_freeze 会像 py2exe 一样混乱。除非知道并花一点时间的人可以对解决方案进行简单的总结。我所有的相关代码都在上面。

标签: python numpy matplotlib scipy py2exe


【解决方案1】:

好像是这个底部提到的问题:http://www.py2exe.org/index.cgi/MatPlotLib

看来您需要对 mlab.py 进行一些小改动:

psd.__doc__ = psd.__doc__ % kwdocd

if psd.__doc__ is not None:
    psd.__doc__ = psd.__doc__ % kwdocd
else:
    psd.__doc__ = ""

如果你还没有看到这个页面,我就是这样到达那里的:http://www.py2exe.org/index.cgi/WorkingWithVariousPackagesAndModules

【讨论】:

    【解决方案2】:

    正如其他人所提到的,py2exe 似乎需要根据具体情况进行丑陋的随机修复......似乎没有办法解决它。此外,一些错误拒绝消失,不会影响程序,但会导致程序通知用户退出后创建了错误日志。为避免这种情况,我使用以下代码:

    import sys
    IS_USING_PY2EXE = hasattr(sys, "frozen")
    
    # Redirect output to a file if this program is compiled.     
    if IS_USING_PY2EXE:
        # Redirect log to a file.
        LOG_FILENAME = os.path.join(logDir, "myfile.log")
        print('Redirecting Stderr... to %s' % LOG_FILENAME)
        logFile = open(os.path.join(LOG_FILENAME),"w") # a --> append, "w" --> write
    
        sys.stderr = logFile
        sys.stdout = logFile
    

    【讨论】:

      【解决方案3】:

      这可能只是我很愚蠢,但你为什么不尝试将你的 scipy 从 0.8.0b1 更新到 0.8.0 并对 matplotlib 做同样的事情呢? Numpy 1.4.1 应该还可以。

      【讨论】:

        猜你喜欢
        • 2016-11-06
        • 1970-01-01
        • 1970-01-01
        • 2022-01-17
        • 1970-01-01
        • 2017-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多