Wie verwende ich sys.exit (0) in einem Arcpy-Skript, um vorzeitig zu beenden, ohne dass eine Fehlermeldung angezeigt wird?

13

Ich habe ein ArcPy-Tool-Skript für ArcGIS 10.0, das zwei Hauptfunktionsabschnitte enthält. Der Benutzer kann wählen, ob der zweite Abschnitt ausgeführt werden soll oder nicht. Wenn der Benutzer den zweiten Abschnitt NICHT ausführt, möchte ich einfach eine Bereinigungsfunktion ausführen und das Skript mit einem sys.exit (0) beenden, ohne dass eine Fehlermeldung im Fenster mit den Werkzeugergebnissen angezeigt wird. In GIS-SE gibt es zwei wichtige Threads zum Beenden von Arcpy-Skripten, die darin enthaltenen Lösungen behandeln die Fehlermeldung jedoch nicht speziell. Die allgemeine Struktur des Codes lautet wie folgt:

import sys
##import arcpy

def CleanUp():
    print 'Cleaning up ...\n'

def finish():
    CleanUp()
    print 'Exiting ...'
    sys.exit(0)

do_more = False  #or True ... input from user

#Section 1:  do some stuff
print 'Doing some stuff ...\n'

if not do_more:
    finish()

#Section 2:  do more stuff
print 'doing more stuff ...'
CleanUp()

Wenn ich diesen Code im Python-Interpreter außerhalb von ArcGIS / arcpy ausführe, funktioniert er wie erwartet und wird ordnungsgemäß ohne Fehlermeldung beendet. In meinem Arcpy-Skript mit der gleichen Struktur wird das Skript jedoch beendet, es wird jedoch eine SystemExit-Fehlermeldung im Tool-Ergebnisfenster angezeigt. Gibt es eine Möglichkeit, das Skript des arcpy-Tools zu veranlassen, die Ausnahme aufzuheben und die SystemExit-Fehlermeldung zu begraben?

Keltenflöte
quelle
Nehmen Sie hier nur einen wilden Stich, aber ist es möglich, dass Sie "del arcpy", bevor Sie das SystemExit in Ihrem Skript aufrufen?
@ Dan - Ich bezweifle es, aber es ist eine interessante Idee ... hmmm ... was zum Teufel. Ich werde es versuchen.
Keltenflöte
1
Vielen Dank für die Veröffentlichung eines übersichtlichen Codebeispiels, das die Logik deutlich macht und die Extras ausschließt. +1
matt wilkie

Antworten:

8

Kurze Antwort: behoben in 10.1. Im Moment müssen Sie eine zusätzliche Einrückungsstufe hinzufügen. Dies kann jedoch zu nützlichen Änderungen an Ihrem Code führen. Jedes Mal, wenn Sie eine große Anzahl von Zeilen in einem einzelnen Skript / einer einzelnen Routine erhalten, sollten Sie darüber nachdenken, diese in kleinere Abschnitte (Funktionen, Klassen) zu unterteilen.

def main():
    <your code>

if __name__ == "__main__":
    try:
        main()
    except SystemExit as err:
        pass
Jason Scheirer
quelle
Danke, Jason. Ja, ich sollte die Kugel beißen und refactor. Es ist nur schwer, das zu tun, wenn der Klient mir den Hals runter atmet. So ist das Leben.
Celticflute
3

ArcPy beeinträchtigt Ihre Python-Umgebung . Kurz gesagt, führen Sie entweder sys.exit () nicht aus oder suchen / rufen Sie die Funktion "Aufräumen vor dem Beenden" (falls vorhanden) von arcpy nicht auf, bevor Sie sys.exit () aufrufen.

Howard Butler
quelle
2
Die Art und Weise, in der die ausführbare Datei von Python verarbeitet wird, sys.exit()ist eine Art schmutziger Trick - der Aufruf exitlöst eine SystemExitAusnahme aus, und der Interpreter der obersten Ebene, der normalerweise einen Traceback ausgibt, erkennt den Ausnahmetyp und beendet den Interpreter. Das Einbetten eines Python-Interpreters in eine andere Anwendung, z. B. die ArcGIS-Familie von ausführbaren Dateien, erfordert eine nicht unerhebliche Menge an implementierungsspezifischem Code wie diesen.
Jason Scheirer
2

Ich weiß nicht, wie ich die SystemExit-Fehlermeldung "begraben" kann, aber Sie können Ihren Code immer neu strukturieren, um den Aufruf von sys.exit zu vermeiden

import sys
##import arcpy

def DoMoreStuff():
    print 'doing more stuff ...'

def CleanUp():
    print 'Cleaning up ...'

def finish():
    CleanUp()
    print 'Exiting ...'

do_more = False  #or True ... input from user

#Section 1:  do some stuff
print 'Doing some stuff ...'

if do_more:DoMoreStuff()

finish()
user2856
quelle
Stimmt, aber die beiden Abschnitte in meinem Arcpy-Skript sind ziemlich umfangreich. Ich würde lieber keine weitere Einrückungsebene erstellen und mich mit den sich daraus ergebenden Scoping-Problemen befassen müssen ... aber ja, das wäre eine Lösung. Wirklich frustrierend ist, dass die Fehlermeldung nur angezeigt wird, wenn Sie in arcpy sys.exit verwenden. In regulärem Python wird die Nachricht nicht veröffentlicht, da die SystemExit-Ausnahme nicht als Fehler angesehen wird.
Keltenflöte