Daten an Subprocess übergeben bzw. im Subprocess auslesen ?

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.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Dienstag 17. Januar 2006, 18:01

Hallo,
ich habe mich in die Pipe-, Popen-, Subprocess- Sachen ein wenig eingelesen, aber bin doch verwirrt, wie das alles funktioniert. Ich will Folgendes:

Main Hauptprogramm ruft mit

Code: Alles auswählen

pz1 = subprocess.Popen('C:/Python/dist/Modul_1.exe')
ein anderes Programm auf. In diesem Programm sollen zwei Variablen weiterverarbeitet werden,
welche vom aufrufenden Programm übergeben werden sollen. Wie bekomme ich:

a) die Variablen (z.b. x und y) über subprocess() in das andere Programm transferiert (write ?, return ?,send ?)

b) wie lese ich in dem anderen Programm die übergebenen Daten aus (read ? readline ? input ?)

Ich weiss, es gibt 'stin' und 'stout'. Aber wie kommunizieren die miteinander ? Hat vieleicht einer ein klitzekleines, konkretes Beispiel parat ?

Wäre sehr dankbar !
Seven
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Dienstag 17. Januar 2006, 18:39

read() liest von stdout des Subprocesses, write() schreibt an stdin des Subprozesses
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dienstag 17. Januar 2006, 20:02


CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Dienstag 17. Januar 2006, 21:27

snakeseven hat geschrieben:Ich weiss, es gibt 'stin' und 'stout'. Aber wie kommunizieren die miteinander ? Hat vieleicht einer ein klitzekleines, konkretes Beispiel parat ?
Hi Seven!

Vielleicht bringt dich das weiter:
http://www.python-forum.de/viewtopic.php?p=29406#29406

Das soll aber nur eine der vielen Möglichkeiten darstellen.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Dienstag 17. Januar 2006, 21:35

Hi Seven!

Wenn du das aufrufende Programm auch mit anderen Programmiersprachen oder einfach nur über die Shell aufrufen können möchtest, dann solltest du darüber nachdenken, ob es nicht doch besser ist, die Parameter über die Kommandozeile zu übergeben zu lassen.

Wie so etwas aussehen kann, demonstriert folgendes Skript. (siehe `def parse_options():`)
http://www.python-forum.de/viewtopic.php?p=9536#9536

Lass dich bitte nicht von den vielen möglichen Parametern im Programm abschrecken. So etwas funktioniert auch mit weniger. ;-)

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Dienstag 17. Januar 2006, 21:51

Vielen Dank !!
Das sieht genau nach dem aus, was ich suche.
Bei mir ruft ein Pythonscript ein anderes (compiliertes) Pythonscript auf, das dürfte mit den Infos jetzt funktionieren. Werde mich gleich morgen ranmachen, es auszuprobieren.

Grüße, Seven
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Dienstag 17. Januar 2006, 22:23

Ich hab das erste Beispiel http://www.python-forum.de/viewtopic.php?t=4941 von Gerold ein bisschen verändert, weil mittels cPickle.load/dump auch bidirektionale Kommunikation möglich ist. Wenn Dich das interessiert, guck nochmal mach.

--- Heiko.
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 18. Januar 2006, 07:14

snakeseven hat geschrieben:Bei mir ruft ein Pythonscript ein anderes (compiliertes) Pythonscript auf
Moment mal! Du rufst ein anderes Python-Skript auf? Warum dann überhaupt über subprocess???
Warum importierst du es nicht einfach und rufst gezielt eine Methode/Funktion auf?
Eine andere Möglichkeit wird beim Python-Server gemacht, es ruft das andere Skript über execfile() auf.

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Mittwoch 18. Januar 2006, 07:47

Moment mal! Du rufst ein anderes Python-Skript auf? Warum dann überhaupt über subprocess???
Warum importierst du es nicht einfach und rufst gezielt eine Methode/Funktion auf?
Eine andere Möglichkeit wird beim Python-Server gemacht, es ruft das andere Skript über execfile() auf.
Es ist ein wenig komplexer. Ein Hauptprozess ruft je nach Bedarf Nebenprozesse auf und terminiert die anschließend wieder. Diese Nebenprozesse bekommen Daten übergeben, arbeiten sie ab und tschüss.
Das ganze ist eine serverbasiserte Anwendung, die je nach Anforderung des Users ein eigenes, auf diese Anforderung zugeschnittenes Programm startet. Der Prozesshandler hat zudem die Aufgabe, die Funktionstüchtigkeit der Nebenprozesse zu überprüfen und erstellt Fehler- und andere Protokolle. Ich finde die Lösung mit den Subprozessen am einfachsten, weil dann auch mehrere parallel arbeiten können. Mit execfile() oder Popen2() kann ich Programme zwar starten, aber nicht wieder beenden. Ist mir jedenfalls nicht gelungen.

Gruss, Seven
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 18. Januar 2006, 08:01

Nimmt man dafür dann nicht besser RPC ?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Mittwoch 18. Januar 2006, 08:46

jens hat geschrieben:Nimmt man dafür dann nicht besser RPC ?
Kenn ich nicht !? Noch ne neue Baustelle wollte ich eigendlich nicht aufmachen. :roll: Werde mich aber mal damit beschäftigen. Danke für den Tipp ! Seven
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Mittwoch 18. Januar 2006, 08:57

@Gerold: Hi, wenn ich dein Sender-Empfänger Beispiel starte, bekome ich eine Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/Ablage/Python/PythonScripte/sender.py", line 54, in -toplevel-
    main()
  File "C:/Ablage/Python/PythonScripte/sender.py", line 38, in main
    cwd = os.curdir
  File "C:\Programme\Python24\lib\subprocess.py", line 533, in __init__
    (p2cread, p2cwrite,
  File "C:\Programme\Python24\lib\subprocess.py", line 623, in _get_handles
    errwrite = self._make_inheritable(errwrite)
  File "C:\Programme\Python24\lib\subprocess.py", line 634, in _make_inheritable
    DUPLICATE_SAME_ACCESS)
TypeError: an integer is required
Gruss, Seven
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 18. Januar 2006, 10:10

snakeseven hat geschrieben:@Gerold: Hi, wenn ich dein Sender-Empfänger Beispiel starte, bekome ich eine Fehlermeldung:
[...]
TypeError: an integer is required[/code]
Hi Seven!

Ich bin paff -- ehrlich. :shock:
Soeben habe ich das Skript unter Windows getestet. So wie ich meistens einen **kleinen** Test unter Windows mache. -- Mit Idle. --

Ich habe die gleiche Fehlermeldung wie du bekommen. Nach ein paar Minuten des sinnlosen herumprobierens habe ich das Skript im WingIDE geöffnet, damit ich besser debuggen kann. Siehe da im WingIDE funktionierte es ohne Probleme. Dann probierte ich es noch über die Kommandozeile aus. Ebenfalls kein Problem.

Das ist mein erstes Skript, das sich nicht dazu überreden lässt, im Idle zu funktionieren.

Vielleicht funktioniert es ja mit **os.popen2** im Idle, aber das kannst du ja selber ausprobieren.

lg
Gerold
:-)
Zuletzt geändert von gerold am Mittwoch 18. Januar 2006, 10:27, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 18. Januar 2006, 10:19

Und wieder ein Grund mehr von der IDLE abzuraten ;)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Mittwoch 18. Januar 2006, 12:06

Hi,
ich muss nochmal zum grundsätzlichen Verständnis nachbohren:
Stdin und Stdout sind der Standardinput bzw. - Output von was: subprocess ?, sys ?
Ich gehe jetzt erstmal davon aus, dass Stdin/Stdout existieren und mir zur Verfügung stehen:

Beispiel: Ich habe zwei Prozesse, einen Main- und einen Subprozess.

Möglichkeit 1:
Mit subproz.stdin.write() schickt der Mainprozess Daten an Stdin.
Mit sys.stdin.read() holt sich der Subprozess die Daten dort ab.
Würde der Subprozess widerum Daten erzeugen, so könnte er diese mit sys.stdout.write()
an Stdout schicken. Und der Mainprozess könnte sie sich dort mit
prozess.stdout.read() abholen.

Möglichkeit 2:
Auf Stdin kann immer nur write() angewendet werden und auf Stdout immer nur read().
Das hieße, daß der Mainprozess mit subproz.stdin.write() die Daten an den Stdin vom Subprozess schickt.
Aus der Sicht vom Subprozess gibt es aber kein Stdin sondern nur den Stdout des Mainprozesses.
Also muss sich Subprozess die Daten mit sys.stdout.read() dort abholen. Das hieße, wenn ich mich nicht irre,
daß physikalisch Stdin = Stdout ist ?

Sorry für eventuelle Verwirrung, aber nur so kann ich verstehen, was ich da überhaupt mache.
Gruss, Seven
Antworten