"Slave.py" von "Master.py" mehrfach neu starten und neu initialisieren lassen

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
PeB
User
Beiträge: 6
Registriert: Samstag 24. April 2021, 18:19

Mein Problem sollte eigentlich trivial sein, irgendwie beiße ich mir aber trotzdem die Zähne daran aus:

Ich möchte eine py (Slave.py) von einer anderen py (Master.py) starten/ausführen lassen. Und zwar mehrfach, wobei die Slave.py immer vollständig neu gestartet wird, d.h. auch alle dortigen Variablen und dortigen Importe bei jedem Start etc. neu initialisiert werden. Als Schmankerl möchte ich bei jedem Neustart der Slave.py durch die Master.py jeweils andere Variablen-Werte übergeben können.

Ich arbeite in WIN10 mit der Python IDLE und habe Python 3.8.3.

Gibt es eine Lösung, und am Besten auch noch eine einfache?
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Lösung ist trivial: schreibe ein richtiges Modul, das keine Nebeneffekte hat und du eine Funktion hast, die du mit den gewünschten Parametern beliebig oft aufrufen kannst.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Üblicherweise macht man das nicht. Sondern erstellt zb einfach eine Klasse, und die hat allen Zustand. Und kann das Objekt dann abräumen & ein neues erzeugen.
PeB
User
Beiträge: 6
Registriert: Samstag 24. April 2021, 18:19

Hat nicht jemand eine wirkliche Antwort in petto?
TenchiMuyo1984
User
Beiträge: 18
Registriert: Donnerstag 17. Januar 2019, 21:17

Du hast doch alle relevanten Antworten bekommen.
Oder brauchst du ein Bsp. in Form einer Implementierung?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das subprocess Modul enthält alle notwendigen Utensilien, um dein Problem zu lösen. Es gibt auch schön viele Beispiele. Viel Erfolg.
PeB
User
Beiträge: 6
Registriert: Samstag 24. April 2021, 18:19

Ich denke, ich sollte die Frage vielleicht noch mal nachvollziehbarer beschreiben:

Bei der "Slave" genannten py handelt es sich um ein ziemlich umfangreiches Programm (> 1000 Zeilen), dass soweit für sich steht und läuft. Im Kern bereitet es einen Datenstrom auf und schickt das dann durch ein neuronales Netz mit entsprechenden Auswertungen. Für einen Durchlauf braucht es zwischen 1 bis 12 Stunden. Danach muss die Slave.py beendet und mit geänderten Eingangs-Parametern neu gestartet werden, schon weil die KI (KERAS etc.) den Parameterwechsel ansonsten nicht zuverlässig verträgt. Und so on. Das möchte ich nun von der Master-py steuern lassen, aber irgendwie funkt das überhaupt nicht.

Wenn ich mit import und reload arbeite, wird die Slave.py nicht wirklich komplett zurückgesetzt und neu gestartet.

Meine Versuche mit subprozess haben mich auch nicht zum Ziel gebracht:

Wenn ich in der Master.py schreibe:

import subprocess
import sys
proc = subprocess.Popen(["python", "Slave.py"],stdout=subprocess.PIPE, shell=True)
stddata = proc.communicate()
print("stddata: ",stddata)

habe ich gleich mehrere Probleme:
1. Die Slave.py wird nicht vollständig ausgeführt.
2. Die Slave.py läuft nicht in der Python.IDLE
3. Ich bekomme Parameter nicht von der Master.py an die Slave.py übergeben, auch wenn ich in der Slave.py z.B. schreibe
import Master
a = Master.a
4. Auch ist die Rückgabe und Anzeige der print-Ausgaben der Slave.py in der IDLE ist nicht vollständig.

Das ganze subprocess-Thema ist mir fremd und erschließt sich mir für mein spezielles Problem auch aus den Beispielen nicht. Also für eine konkrete Hilfe, wie ich dass schreiben kann, wäre ich dankbar.
Benutzeravatar
__blackjack__
User
Beiträge: 14055
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@PeB: Ich denke die allererste Antwort von Sirius3 trifft es immer noch. Die gilt im Grund auch ziemlich generell. Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Der Import eines Moduls sollte darüber hinaus keine weiteren Effekte haben. Dann hast Du in dem Modul eine Funktion, welche die Aufgabe erledigt, und die benötigte Parameter als Argumente beim Aufruf übergeben bekommt.

Vergiss im Zusammenhang von laufenden Programmen mal IDLE und dort import und reload. Das ist eine IDE, und keine Umgebung für Programme deren Vorhandensein ein Programm voraussetzen sollte. Konsolenprogramme müssen letztlich ohne IDE in einer Konsole laufen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Rotmilan
User
Beiträge: 32
Registriert: Mittwoch 30. Dezember 2020, 21:59
Wohnort: Nordbayern

ich wurschtel ja auch immer noch mit python rum und habe keine wirklich große ahnung,.

wie man beim starten eines programmes werte übergibt weiß ich erst recht nicht. ich würde das jetzt vom ansatz so lösen, dass ich den master die zu übergebenden werte in eine datei (text/xml...) schreiben lassen. die könnte dann die slave wieder auslesen.

soweit mal meine idee für das übergeben der werte, falls dir das schwierigkeiten macht - für alles andere bin ich noch unqualiizierter und halte mich raus ;-)
PeB
User
Beiträge: 6
Registriert: Samstag 24. April 2021, 18:19

Rotmilan hat geschrieben: Sonntag 25. April 2021, 11:43 ich wurschtel ja auch immer noch mit python rum und habe keine wirklich große ahnung,.

wie man beim starten eines programmes werte übergibt weiß ich erst recht nicht. ich würde das jetzt vom ansatz so lösen, dass ich den master die zu übergebenden werte in eine datei (text/xml...) schreiben lassen. die könnte dann die slave wieder auslesen.

soweit mal meine idee für das übergeben der werte, falls dir das schwierigkeiten macht - für alles andere bin ich noch unqualiizierter und halte mich raus ;-)
Hey! Das ist zumindest mal eine Idee! Danke!
PeB
User
Beiträge: 6
Registriert: Samstag 24. April 2021, 18:19

habe etwas gefunden, das zumindest die Slave.py in der IDLE executiert:

exec(open('Slave_01.py').read())

https://stackoverflow.com/questions/172 ... tive-shell
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bild
Benutzeravatar
noisefloor
User
Beiträge: 4194
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
habe etwas gefunden, das zumindest die Slave.py in der IDLE executiert:
Dann vergiß' einfach wieder, dass du diese Codezeile je gesehen hast. Das ist ja ein ganz schlimmer Würg-Around, macht man so nicht.

Grundsätzlich: wenn du aus Pyhton-Programm A Python-Programm B mittels `subprocess` oder so ausführst, dann machst du in 99,9% der Fälle einen Fehler.

Wie es richtig geht, wurde dir mehrfach gesagt. Wenn du das nicht verstehst solltest du unbedingt nachfragen anstatt irgendwelchen schlimmen Hacks zu probieren...

Wie gut kannst du denn Python? Hast du verstanden, wie Funktionen und Rückgabewerte funktionieren? Weißt du, wie man einen eigene Klasse schreibt und instanziert? Weißt da, was das `import` Statement macht?

Gruß, noisefloor
Benutzeravatar
ThomasL
User
Beiträge: 1379
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

PeB hat geschrieben: Sonntag 25. April 2021, 10:27 Bei der "Slave" genannten py handelt es sich um ein ziemlich umfangreiches Programm (> 1000 Zeilen), dass soweit für sich steht und läuft. Im Kern bereitet es einen Datenstrom auf und schickt das dann durch ein neuronales Netz mit entsprechenden Auswertungen. Für einen Durchlauf braucht es zwischen 1 bis 12 Stunden. Danach muss die Slave.py beendet und mit geänderten Eingangs-Parametern neu gestartet werden, schon weil die KI (KERAS etc.) den Parameterwechsel ansonsten nicht zuverlässig verträgt.
Wenn man das ordentlich programmiert, dann verträgt Tensorflow/Keras jeglichen Parameterwechsel.
Wenn dem nicht so ist, sollte dieses "umfangreiches Programm" überarbeitet werden
und mit master.py zusammengelegt werden.
Alles andere ist Frickelei allerübelster Art.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
PeB
User
Beiträge: 6
Registriert: Samstag 24. April 2021, 18:19

Also da fällt mir ein Witz ein:
Geht ein Mann, weil er nicht schlafen kann, nachts spazieren. Da sieht er einen anderen Mann unter einer Laterne, der dort offensichtlich etwas sucht. Er fragt ihn daher: "Haben Sie etwas verloren?" "Ja, meinen Schlüssel", antwortet der andere Mann. "Hier?" hakt der Mann nach. "Nein, dort hinten irgendwo", erwidert der andere Mann. "Aber warum suchen Sie denn dann hier?", fragt der Mann nun verwundert. "Weil hier Licht ist."

Also wenn man das so formuliert, läuft es - gegen alle Unkenrufe hier - stabil durch:

SlaveDatei = "Slave.py"
with open(SlaveDatei) as f:
code = compile(f.read(), SlaveDatei, 'exec')
exec(code)

Mit dem Statement kann man die Slave.py wiederholt und "fresh" durchlaufen lassen. Die Print-Ausgaben erfolgen in der IDLE auch so, als würde die Slave.py standalone laufen. Und schön ist auch, dass die Master.py erst weitermacht, wenn ein Durchlauf der Slave.py beendet ist. Was bisher einzig noch nicht funkt, ist, innerhalb des Statements Variablenwerte von der Master.py an die Slave.py zu übergeben.
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Fällt ein Mann aus dem Fenster im 38. Stockwerk. Als er am 10. vorbeifällt denkt er sich: ›Glück gehabt, nichts schlimmes passiert‹.
Du näherst dich dem Boden, wenn Du merkst, dass Du keine Variablenwerte übergeben kannst und auch Deine Module nicht neu geladen werden.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn du deinen 1000-Zeilen-Mystery-Code in eine vernuenftige Form bringen wuerdest, dann koennte das auch "fresh" durchlaufen. Und als Bonus obendrauf auch noch Argumente uebergeben!

Aber schiess dir ruhig weiterhin von hinten durch die Brust ins Auge. Es gibt Leute, denen reicht der Hinweis, dass eine Herdplatte heiss ist. Andere lernen erst nach dem dritten Hauttransplantat. Manche nie.
Antworten