2011-02-04 14 views
7

Próbuję użyć py2exe-0.6.9.win32 aby zakończyć aplikację, która mam napisane w Python2.6.5 użyciu następujących bibliotek obiektów związanych z nazwami Ściągnij plik:py2exe i nie NumPy dogadują

matplotlib -0.99.3.win32

numpy-1.4.1-win32

scipy-0.8.0b1 Win32

wxPython2.8 Win32-unicode-2.8.11.0

Otrzymuję komunikaty o błędach, gdy próbuję uruchomić wynikowy plik .exe. W tej chwili komunikat o błędzie jest związany z numpy, ale wcześniej otrzymywałem coś niezwiązanego z plikami danych matplot lib, a tym samym blokowanie uruchamiania mojego pliku exe.

Zamiast pisać milę kodu i wszystkie komunikaty o błędach, publikuję ogólne pytanie: Czy ktoś może pokazać mi instrukcje dotyczące tego, że wszystkie te biblioteki obiektów i wersje grają dobrze razem przy użyciu py2exe, aby utworzyć działające plik exe?

Czytałem rzeczy, które pojawiają się w wyszukiwaniach Google na ten temat, ale wydaje się, że pościg głupi, że każdy używa różnych wersji różnych rzeczy. Mogę zmienić niektóre wersje niektórych z tych bibliotek obiektów, jeśli to robi różnicę, ale napisałem już 5000 linii kodu w tej aplikacji do przetwarzania sygnału i wolałbym nie zapisywać go ponownie, jeśli możliwy.


EDIT:

Tutaj jest uproszczoną wersją mojego kodu w pliku o nazwie GUIdiagnostics.py że zrobiłem przetestować zdolność mojego skryptu py2exe importowania wszystkie biblioteki, które trzeba w moja prawdziwa aplikacja:

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

Oto kod dla setup.py, który to plik zawierający mój kod 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 
) 

ten kod wpisując następującą linię do linii poleceń systemu Windows (cmd.exe) zgodnie z poniższym linkiem:

setup.py py2exe 

py2exe następnie biegnie, ale gdy próbuję uruchomić otrzymaną plik exe, tworzy plik dziennika zawierający następujący komunikat:

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' 

może ktoś mi pokazać jak edytować setup.py tak że py2exe może stworzyć użyteczną wykonywalny bieganie, scipy numpy, matplotlib, itp?


DRUGA EDYCJA:

OK. Próbowałem dzisiaj rady RC, teraz, gdy mam do tego świeży umysł i mam ten sam błąd, ale włączam go poniżej. Oto kod pliku o nazwie cxsetup.py, który utworzyłem zgodnie z szablonem pod adresem: 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")]) 

Niestety działa to w wierszu poleceń (cmd.exe) za pomocą polecenia:

python cxsetup.py build 

generuje następujący błąd w linii komend:

ImportError: No module named cx_Freeze 

Katalog w wiersz poleceń jest katalogiem dla mojej aplikacji, który znajduje się w podfolderze pulpitu. To różni się od katalogu dla aplikacji Pythona, ale zakładam, że cmd.exe może to zrozumieć, ponieważ Python może to zrozumieć. Czy się mylę? Jako test, dodałem poniższy wiersz kodu do pierwszej linii cxsetup.py:

import matplotlib 

Ale który wygenerował prawie identyczny błąd:

ImportError: No module named matplotlib 

starałem się zachować ten wątek skupiony i krótki, ale robi się długo. Czy ktoś może mi w tym pomóc? Nie chciałbym wykonać całą pracę przełączania tylko cx_freeze do stwierdzenia, że ​​nie może pracować z numpy, matplotlib, scipy itp

+0

może możesz spróbować z cxfreeze i zobaczyć, czy to pomaga w tworzeniu działającego –

+0

(usunięte przepraszam) –

+0

Dziękuję. Próbowałem, ale otrzymuję inny komunikat o błędzie od cxfreeze i wolałbym skupić się na tym wątku, aby nie mylić ludzi z zbyt dużą ilością kodu lub zbyt dużą ilością komunikatów o błędach. Ten aspekt programowania jest dla mnie nowością. – MedicalMath

Odpowiedz

0

Jak już wspomnieli inni, py2exe wydaje się wymagać brzydkich, losowych poprawek na podstawie każdego przypadku ... wydaje się, że nie ma na to sposobu. Ponadto niektóre błędy nie pozwalają odejść i nie mają wpływu na program, ale powodują, że program informuje użytkownika, że ​​dziennik błędów został utworzony po wyjściu. Aby tego uniknąć, używam tego kodu:

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

Może to tylko ja głupi, ale dlaczego nie spróbować zaktualizować scipy z 0.8.0b1 do 0.8.0 i zrobić to samo z matplotlib? Numpy 1.4.1 nadal powinno być w porządku.