Jak użyć sys.exit (0) w skrypcie arcpy, aby wyjść wcześniej bez wyświetlania komunikatu o błędzie?

13

Mam skrypt narzędzia Arcpy dla ArcGIS 10.0, który ma dwie główne sekcje funkcjonalne. Użytkownik może wybrać, czy uruchomić drugą sekcję. Jeśli użytkownik zdecyduje się NIE uruchamiać drugiej sekcji, chcę po prostu uruchomić funkcję czyszczenia i wyjść ze skryptu za pomocą sys.exit (0) bez wyświetlania komunikatu o błędzie w oknie wyników narzędzia. Istnieją dwa główne wątki w GIS-SE dotyczące wychodzenia ze skryptów arcpy, ale rozwiązania w nich zawarte nie uwzględniają komunikatu o błędzie. Ogólna struktura kodu jest następująca:

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()

Jeśli uruchomię ten kod w interpretera Pythona poza ArcGIS / arcpy, działa on tak, jakbym się spodziewał, wychodząc z gracją bez żadnego komunikatu o błędzie; jednak w moim skrypcie o tej samej strukturze skrypt kończy działanie, ale komunikat o błędzie SystemExit jest wysyłany do okna wyników narzędzia. Czy istnieje sposób, aby skrypt narzędzia Arcpy zjadł wyjątek i zakopał komunikat o błędzie SystemExit?

flet celtycki
źródło
Po prostu zaciągam się tutaj, ale czy to możliwe, że możesz „del arcpy” przed wywołaniem SystemExit w skrypcie?
@ Dan - Wątpię, ale to ciekawy pomysł ... hmmm ... co do cholery. Dam mu wir.
Flet celtycki
1
dziękuję za opublikowanie zwięzłego kodu, który jasno ilustruje logikę i pomija dodatki. +1
matt wilkie

Odpowiedzi:

8

Krótka odpowiedź: poprawiona w 10.1. Na razie musisz dodać dodatkowy poziom wcięcia. Może to jednak zachęcić do przydatnego refaktoryzacji kodu. Za każdym razem, gdy otrzymujesz dużą liczbę wierszy w jednym skrypcie / procedurze, powinieneś pomyśleć o podzieleniu go na mniejsze sekcje (funkcje, klasy).

def main():
    <your code>

if __name__ == "__main__":
    try:
        main()
    except SystemExit as err:
        pass
Jason Scheirer
źródło
Dzięki, Jason. Tak, powinienem ugryźć kulę i refaktora. Ciężko to zrobić, gdy klient oddycha mi po szyi. Takie jest życie.
celticflute
3

ArcPy działa w środowisku Python . Krótko mówiąc, nie wykonuj sys.exit () lub znajdź / wywołaj funkcję „cleanup-before-exit” (jeśli taka istnieje) arcpy przed wywołaniem sys.exit ().

Howard Butler
źródło
2
Sposób, w jaki pliki wykonywalne Pythona są traktowane sys.exit()jako brudna sztuczka - wywoływanie exitwywołuje SystemExitwyjątek, a interpreter najwyższego poziomu, który normalnie drukuje informacje zwrotne, wykryje typ wyjątku i zakończy działanie interpretera. Osadzenie interpretera Pythona w innej aplikacji, takiej jak rodzina plików wykonywalnych ArcGIS, wymaga nietrywialnej ilości kodu specyficznego dla implementacji, takiego jak ten.
Jason Scheirer
2

Nie wiem, jak „zakopać” komunikat o błędzie SystemExit, ale zawsze możesz zmienić strukturę kodu, aby uniknąć wywoływania sys.exit

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()
użytkownik2856
źródło
To prawda, ale dwie sekcje mojego skryptu są dość duże. Wolałbym nie tworzyć kolejnego poziomu wcięć i musiałbym zająć się problemami określania zakresu, które mogłyby się pojawić ... ale tak, to byłoby rozwiązanie. Naprawdę frustrujące jest to, że komunikat o błędzie pojawia się tylko wtedy, gdy używasz sys.exit w arcpy. W zwykłym Pythonie komunikat nie jest wysyłany, ponieważ wyjątek SystemExit nie jest uważany za błąd.
Flet celtycki