Aufruf und Übergabe

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
cle1986
User
Beiträge: 18
Registriert: Donnerstag 7. September 2006, 12:44

Hallo!

Ich habe im Forum und im Google gesucht und auch etwas gefunden, nur kann ich nicht wirklich was damit anfangen. Darum beschreibe ich nochmals mein Problem und hoffe eine brauchbare Antwort zu bekommen.

Also ich habe eine GUI in wxPython geschrieben. In dieser GUI gibt man die entsprechenden Daten ein und wählt ein Pythonfile aus.
Anschliessend klickt man auf Start.

So und nun soll ein Pythonfile folgendermassen aufgerufen werden: "start.py run" und es sollen die eingegebenen Variablen an das aufzurufende File übergeben.

Ich habe mir folgende Befehle angesehen und ausprobiert, aber mit keinem bin ich wirklich auf das Ergebnis gestossen, auf das ich kommen will.
call(), system(), subprocess() und execfile()

Ausserdem weiss ich auch nicht, wie ich die Übergebenen Variablen im aus zu führenden Skript übernehme.

Und zu guter letzt möchte ich noch, dass alle Ausgaben im Fenster stdout/stderr angezeigt werden. Denn wenn ich die GUI unter Linux aufrufe, dann werden print Ausgaben im Fenster stdout/stderr ausgegeben, die Ausgaben des aufzurufenden Skripts allerdings in dem Shellfenster, aus dem aus ich die GUI gestartet habe.
BlackJack

Die Frage ist ist etwas vage formuliert.
cle1986 hat geschrieben:Also ich habe eine GUI in wxPython geschrieben. In dieser GUI gibt man die entsprechenden Daten ein und wählt ein Pythonfile aus.
Anschliessend klickt man auf Start.

So und nun soll ein Pythonfile folgendermassen aufgerufen werden: "start.py run" und es sollen die eingegebenen Variablen an das aufzurufende File übergeben.
Wie sollen sie übergeben werden? Und was sind das für Daten? Du könntest `optparse` benutzen und die Daten als Argumente an das Programm übergeben, oder beim Aufrufer auf stdout ausgeben und im gestarteten Programm über stdin einlesen, oder die Daten in eine temporäre Datei schreiben, oder XMP-RPC zur Kommunikation nutzen, usw.
Ich habe mir folgende Befehle angesehen und ausprobiert, aber mit keinem bin ich wirklich auf das Ergebnis gestossen, auf das ich kommen will.
call(), system(), subprocess() und execfile()
Von denen ist das `subprocess` Modul das flexibelste. `call()` und `system()` sind ähnlich und starten ein externes Programm synchron, d.h. das aufrufende Programm läuft erst weiter wenn das gestartete Programm beendet ist. Hier kommen für die Datenübergabe nur die Kommandozeile und temporäre Dateien in Frage.
Und zu guter letzt möchte ich noch, dass alle Ausgaben im Fenster stdout/stderr angezeigt werden. Denn wenn ich die GUI unter Linux aufrufe, dann werden print Ausgaben im Fenster stdout/stderr ausgegeben, die Ausgaben des aufzurufenden Skripts allerdings in dem Shellfenster, aus dem aus ich die GUI gestartet habe.
Welches stdout/stderr Fenster? Wie hast Du das programmiert?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

BlackJack hat geschrieben:Welches stdout/stderr Fenster?
Hi BlackJack!

Er meint dieses Fenster: http://www.python-forum.de/topic-5721.html

Alles was ab der Initialisierung von wx.App() oder wx.PySimpleApp() nach STDOUT geschrieben wird, wird dann in diesem Fenster angezeigt.

Damit auch die Ausgabe der aufgerufenen Programme in diesem Fenster angezeigt wird, muss die Ausgabe des aufgerufenen Programmes mit ``os.popen()`` oder ``subprocess`` eingefangen und explizit noch mit print an STDOUT gesendet werden.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
cle1986
User
Beiträge: 18
Registriert: Donnerstag 7. September 2006, 12:44

BlackJack hat geschrieben:Die Frage ist ist etwas vage formuliert.
cle1986 hat geschrieben:Also ich habe eine GUI in wxPython geschrieben. In dieser GUI gibt man die entsprechenden Daten ein und wählt ein Pythonfile aus.
Anschliessend klickt man auf Start.

So und nun soll ein Pythonfile folgendermassen aufgerufen werden: "start.py run" und es sollen die eingegebenen Variablen an das aufzurufende File übergeben.
Wie sollen sie übergeben werden? Und was sind das für Daten? Du könntest `optparse` benutzen und die Daten als Argumente an das Programm übergeben, oder beim Aufrufer auf stdout ausgeben und im gestarteten Programm über stdin einlesen, oder die Daten in eine temporäre Datei schreiben, oder XMP-RPC zur Kommunikation nutzen, usw.
Also ich brauche diese Variablen in dem Skript. Das wie ist mir egal. Es sollte einfach exportieren und importieren gehen. Damit fällt wohl die Temporäre Datei schon weg. Ich werde mir mal optparse anschauen, denn bei popen() habe ich keine Variablenübergabeargumente gesehen.

@gerold

Ja genau dieses Fenster habe ich gemeint. Werde mal versuchen die Ausgaben umzulenken.
cle1986
User
Beiträge: 18
Registriert: Donnerstag 7. September 2006, 12:44

Wie geht das mit dem stdin/stdout?
Also ich meine das ich die Variablen mit stdout in den Buffer schreiben kann
und dann mit stdin im andren Skript weiterverarbeiten kann.

Ich hätte es Mal so probiert:

Code: Alles auswählen

sys.stdout.write("Starting simulation\n")
            temp = self.filet.GetValue()
            os.chdir(os.path.dirname(temp))
            sys.stdout.write(self.starttime.GetValue())
            sys.
            process = subprocess.Popen(temp+" run",bufsize=0,shell=True,stdout=subprocess.PIPE,) 
            print process.stdout.readlines()
            #print process.stdout.read()
            sys.stdout.write("Simulation done")
^Das GUI Skript

Code: Alles auswählen

 self.start = float(sys.stdin.read())
Nur hat das nicht funktioniert
BlackJack

Das gibt mindestens einen `SyntaxError`. Bitte immer den Quelltext veröffentlichen den Du auch wirklich ausprobiert hast.

Minimal funktioniert das so:

Code: Alles auswählen

from subprocess import Popen, STDOUT, PIPE

def main():
    process = Popen('./test2.py', stdin=PIPE, stdout=PIPE, stderr=STDOUT)
    process.stdin.write(str(42))
    process.stdin.close()
    data = process.stdout.read()
    print '>', data, '<'
Und das Empfängerprogramm:

Code: Alles auswählen

import sys

def main():
    data = int(sys.stdin.read())
    print 'on stdout:', data
    sys.stderr.write('on stderr: %d\n' % data)
cle1986
User
Beiträge: 18
Registriert: Donnerstag 7. September 2006, 12:44

Also habe jetzt mal versucht deine Hilfestellung einzubauen:

Code: Alles auswählen

def start(self,evt):
        if(self.filet.GetValue()==""):
            dlg = wx.MessageDialog(None, "Sie haben keine Datei fuer die Simulation ausgewaehlt!",
                                   'Error',style=wx.OK)
            if dlg.ShowModal() == wx.ID_OK:
                dlg.Destroy()
        else:
            sys.stdout.write("Starting simulation\n")
            temp = self.filet.GetValue()
            os.chdir(os.path.dirname(temp))
            sys.stdout.write(self.starttime.GetValue())
            
            process = subprocess.Popen(temp+" run",bufsize=0,shell=True,stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE) 
            process.stdin.write(str(self.starttime.GetValue()))
            process.stdin.write(str(self.endtime.GetValue()))
            process.stdin.write(str(self.stepmax.GetValue()))
            process.stdin.write(str(self.stepmin.GetValue()))
            process.stdin.write(str(self.method.GetStringSelection()))
            process.stdin.close()
            process.stdout.read()
            print process.stdout.readlines() #Sollte die Ausgaben des textbasierten Skriptes anzeigen.
            #print process.stdout.read()
            sys.stdout.write("Simulation done")
^Diesmal poste ich die ganze Funktion und diese habe ich auch getestet.

Empfänger:

Code: Alles auswählen

def main():
	self.start = float(sys.stdin.read())
	self.end = float(sys.stdin.read())
	self.stepmin = float(sys.stdin.read())
	self.stepmin = float(sys.stdin.read())
	self.meth = sys.stdin.read()
Ich bekomme als Ausgabe nur eine Zahl geliefert, die ich in der GUI eingegeben habe. Daher befürchte ich auch, dass die Simulation nicht gestartet wurde.
BlackJack

Die `read()` Methode liest alle Daten bis zum Dateiende ein, d.h. bei Pipes bis die andere Seite die Pipe schliesst. Das bedeutet Du versuchst beim Empfänger die gesamten Daten gleich in der ersten Zeile von `main()` in ein `float` umzuwandeln. Das sollte eigentlich schon eine Fehlermeldung geben.

Beim schreiben sind die Zahlen durch nichts getrennt, das heisst alles "klebt" aneinander. Da wundert mich ein wenig, dass Du keine Fehlermeldung bekommst, beim Versuch das in ein `float` zu wandeln.

Und im Hauptprogramm dürfte so auch nichts ausgegeben werden weil Du mit einem ``process.stdout.read()`` die komplette Antwort liest und dann nichts damit tust. Das `readlines()` in der folgenden Zeile gibt nichts zurück, da die Ausgabe schon komplett gelesen wurde.
Antworten