Von Modul aus in eine Funktion im Hauptprogramm springen?

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
dominik123
User
Beiträge: 35
Registriert: Montag 10. Februar 2014, 08:48

Hallo zusammen,

um einen Testaufbau mittels Python zu automatisieren steuere ich zur Zeit verschiedene Messgeräte mittels SCPI-commands an. Hierzu nutze ich ein Hauptprogramm welches verschiedene Module bzw. Bibliotheken (für jedes Messgerät ein Modul) aufruft. Zur Verarbeitung von Errors würde ich gerne sobald in einem Modul ein Error auftritt zurück ins Hauptprogamm und dort in eine "Error- Funktion" springen. (diese Funktion müsste dann noch verschiedene Schritte abarbeiten um das System in einen sicheren Zustand zu bringen und das Programm anschließend beenden). Gibt es irgend eine Möglichkeit dies zu realisieren?
Eine andere Möglichkeit wäre es wohl eine extra "Error-Bibliothek" einzubinden. Dies möchte ich allerdings gerne vermeiden...

Danke im Voraus!

Viele Grüße,
Dominik
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ja, was du suchst sind Ausnahmen (Exceptions) und werden eigentlich in jedem Python-Tutorial behandelt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
dominik123
User
Beiträge: 35
Registriert: Montag 10. Februar 2014, 08:48

Danke für die schnelle Antwort. Auf Exceptions bin ich auch schon gestoßen, allerdings verstehe ich nicht wie ich mit Hilfe einer solchen in eine Funktion springen kann. Also wie beispielsweise bei einer erfüllten if- Bedingung einen Sprung zurück ins Hauptprogramm realisieren kann.
Benutzeravatar
snafu
User
Beiträge: 6908
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

dominik123 hat geschrieben:Also wie beispielsweise bei einer erfüllten if- Bedingung einen Sprung zurück ins Hauptprogramm realisieren kann.
Grob gesagt etwa nach diesem Muster (und natürlich ohne Deutsch-Englisch-Mischmasch):

Code: Alles auswählen

def unterfunktion(args):
    # viel Code
    if BEDINGUNG:
        raise MyException
    # viel Code

def oberfunktion():
    try:
        unterfunktion(args)
    except MyException:
        do_error_handling()
EDIT: Du sorgst also nicht direkt für den Sprung im Fehlerfall, sondern die Unterfunktion steigt im Falle einer Exception sofort aus und gibt die Kontrolle an die aufrufende Funktion zurück. Diese kann dann entweder die Exception behandeln (was in meinem Beispiel getan wird) oder keine Behandlung vornehmen. Trifft letzteres zu, dann steigt der Aufrufer ebenfalls direkt aus und gibt die Kontrolle abermals an seinen Aufrufer und es gelten für diesen wieder die bereits benannten Regeln. Wenn es keinen Aufrufer mehr gibt, dann steigt der Python-Interpreter mit einer Fehlermeldung aus, die dir auf der Kommandozeile angezeigt wird.
Zuletzt geändert von snafu am Mittwoch 18. Juni 2014, 09:17, insgesamt 2-mal geändert.
BlackJack

@dominik123: Verabschiede Dich von dem Gedanken irgendwo in eine Funktion ”springen” zu wollen. Löse bei Problemen eine Ausnahme aus die im Hauptprogram entsprechend behandelt wird. Zum Beispiel in dem eine Funktion aufgerufen wird.
dominik123
User
Beiträge: 35
Registriert: Montag 10. Februar 2014, 08:48

Vielen Dank!
Auf folgende Art funktioniert meine Fehlerbehandlung jetzt:

Code: Alles auswählen

def oberfunktion():
    try:
        funktion()
        funktion1()
        funktion2()
    except Exception:
        mainprogram.error_handler()
Allerdings frage ich mich trotzdem ob es nicht eine elegantere Möglichkeit gibt, als das gesamte Hauptprogramm innerhalb von "try" auszuführen, da diese Programmierungsweise in einem sehr unübersichtlichen Hauptprogramm enden würde.
BlackJack

@dominik123: Also ich finde das elegant. Und auch überhaupt nicht unübersichtlich, im Gegenteil. Wieso sollte es das sein/werden?

Falls Du wirklich `Exception` behandelst, würde ich ja noch die konkrete Ausnahme an einen Namen binden und an die Fehlerbehandlungsfunktion übergeben, damit man die Chance hat dem Benutzer irgendwie mitzuteilen *welcher* Fehler da eigentlich aufgetreten ist.

Was macht `error_handler()` denn bei Dir? Und `mainprogram` ist hoffentlich nicht das Modul welches das Modul mit der Funktion `oberfunktion` importiert hat, denn zirkuläre importe sollte man vermeiden, die bringen Probleme mit sich und sind ein Anzeichen für einen schlechten Entwurf.
dominik123
User
Beiträge: 35
Registriert: Montag 10. Februar 2014, 08:48

Zur Zeit gibt "error_handler()" nur (aus Testzwecken) eine Ausgabe auf der Konsole aus. Der finale Zweck dieser Funktion wird es sein verschiedene Geräte abzuschalten, bevor das Programm beendet wird.
Ich dachte, dass es eventuell aufgrund der länge des Hauptprogrammes unübersichtlich werden könnte. Aber wenn es das gängige Vorgehen ist, werde ich das ganze so programmieren.
"mainprogram" war tatsächlich das Modul, welches das Modul mit der Funktion "oberfunktion" importiert hat, das habe ich allerdings bereits abgeändert.
Vielen Dank für die Anworten!
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@dominik123: wenn Dein Hauptprogramm zu lang wird, kannst/sollst Du es ja in mehrere Funktionen unterteilen, damit die Übersichtlichkeit gewahrt wird. Soll ganz allgemein am Ende "aufgeräumt" werden, also unabhängig, ob ein Fehler auftritt oder nicht, ist ein "finally"-Block das Richtige.
BlackJack

Und dann gäbe es noch das `atexit`-Modul oder man könnte die Geräte auch mit einem Kontextmanager versehen und die ``with`` verwenden um das Aufräumen sicher zu stellen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

BlackJack hat geschrieben:Und dann gäbe es noch das `atexit`-Modul oder man könnte die Geräte auch mit einem Kontextmanager versehen und die ``with`` verwenden um das Aufräumen sicher zu stellen.
Das ist vermutlich auch die bessere Idee, gerade wenn es um das Handhaben von Resourcen angeht. Die Geräte müssen ja vmtl. so oder so abgeschaltet werden und nicht nur im Fehlerfall.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten