2011-02-04 27 views
7

Estoy tratando de utilizar py2exe-0.6.9.win32 para envolver una aplicación que he escrito en Python2.6.5 usando las siguientes bibliotecas de objetos con nombres de archivo asociados descarga:py2exe y no numpy llevarse bien

matplotlib -0.99.3.win32

numpy-1.4.1-win32

scipy-0.8.0b1-win32

wxPython2.8-win32-Unicode-2.8.11.0

Recibo mensajes de error cuando intento iniciar el archivo .exe resultante. Por el momento, el mensaje de error está relacionado con numpy, aunque antes estaba obteniendo algo relacionado con los archivos de datos de matplot lib que no se cargaban y, por lo tanto, bloqueaba el lanzamiento de mi archivo exe.

En lugar de publicar una milla de código y todos los mensajes de error, estoy publicando una pregunta más general: ¿Puede alguien mostrarme algunas instrucciones para hacer que todas estas bibliotecas de objetos y versiones funcionen bien juntas utilizando py2exe para crear un archivo exe?

He estado leyendo cosas que surgen con las búsquedas de Google sobre el tema, pero parece una búsqueda inútil en el sentido de que todo el mundo está usando versiones diferentes de cosas diferentes. Puedo cambiar algunas de las versiones de algunas de estas bibliotecas de objetos si eso hace la diferencia, pero ya he escrito 5.000 líneas de código en esta aplicación de procesamiento de señal, y preferiría no tener que volver a escribir todo, si posible.


EDIT:

Aquí es una versión simplificada de mi código en un archivo llamado GUIdiagnostics.py que hice para poner a prueba la capacidad de mi guión py2exe para importar todas las bibliotecas que necesito en mi verdadera aplicación:

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() 

Aquí está el código para setup.py, que es el archivo que contiene el código 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 
) 

que ejecuta este código escribiendo la siguiente línea en la interfaz de línea de comandos de Windows (cmd.exe) según el siguiente enlace:

setup.py py2exe 

py2exe entonces funciona, pero cuando trato de poner en marcha el resultante exe, se crea un archivo de registro que contiene el siguiente mensaje:

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' 

puede alguien me enseñe a editar setup.py para que py2exe puede crear un ejecutable utilizable numpy correr, scipy, matplotlib, etc.?


SEGUNDA EDICIÓN:

OK. Intenté el consejo de RC nuevamente hoy, ahora que tengo una nueva mente para esto, y obtuve el mismo error, pero lo incluyo a continuación. Aquí está el código para un archivo llamado cxsetup.py que creé siguiendo la plantilla en: 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")]) 

Desafortunadamente, corriendo en la línea de comandos (cmd.exe) con el comando:

python cxsetup.py build 

genera el error siguiente en la línea de comandos:

ImportError: No module named cx_Freeze 

El directorio en el la línea de comando es el directorio de mi aplicación, que se encuentra en una subcarpeta del escritorio. Eso es diferente al directorio para la aplicación de Python, pero supongo que cmd.exe puede resolverlo porque Python puede resolverlo. ¿Estoy equivocado? Como prueba, añade la siguiente línea de código a la primera línea de cxsetup.py:

import matplotlib 

Pero que generó el error casi idéntico:

ImportError: No module named matplotlib 

he tratado de mantener este hilo centrado y corto, pero se está haciendo algo largo. ¿Alguien puede ayudarme con esto? No me gustaría hacer todo el trabajo de cambiar a cx_Freeze sólo para encontrar que no puede trabajar con numpy, matplotlib, scipy, etc.

+0

quizás podría probar con cxfreeze y ver si ayuda a crear un exe que funcione –

+0

(lo siento) –

+0

Gracias. Intenté eso, pero recibo un mensaje de error diferente de cxfreeze y prefiero mantener este hilo enfocado para no confundir a las personas con demasiados códigos o demasiados mensajes de error. Este aspecto de la programación es nuevo para mí. – MedicalMath

Respuesta

0

Como han mencionado otros, py2exe parece requerir soluciones feas, aleatorias caso por caso ... parece que no hay forma de evitarlo. Además, algunos errores se niegan a desaparecer y no afectan el programa, pero hacen que el programa informe al usuario que se creó un registro de errores después de la salida. Para evitar eso, utilizo este código:

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 
0

Esto podría yo sea estúpida, pero ¿Por qué no tratar de actualizar su scipy de 0.8.0b1 de 0.8.0 y hacer lo mismo con matplotlib? Numpy 1.4.1 todavía debería estar bien.