Fehlerbehandlung mit Python
Fehler sind nicht immer zu vermeiden. Wenn Sie Skripte erstellen, die auf Fehler vorbereitet sind und darauf reagieren können, sparen Sie sich viel Zeit und Nerven. Wenn ein Werkzeug eine Fehlermeldung zurückgibt, erzeugt ArcPy einen Systemfehler bzw. eine Ausnahme. In Python können Sie eine Reihe von Strukturen und Methoden bereitstellen, mit denen Ausnahmen verarbeitet werden. Skripte können natürlich auch aus anderen Gründen, die nichts mit dem Geoverarbeitungswerkzeug zu tun haben, fehlschlagen. Auch diese Fehler müssen abgefangen und entsprechend behandelt werden. In den folgenden Abschnitten werden einige Vorgehensweisen erläutert, die Ihnen die Grundlagen der Fehlerbehandlung in Python vorstellen.
Wenn ein Werkzeug eine Fehlermeldung schreibt, erzeugt ArcPy einen Systemfehler bzw. eine Ausnahme. Mit Python können Sie eine Routine schreiben, die bei jedem Systemfehler automatisch ausgeführt wird. In dieser Fehlerverarbeitungsroutine können Sie die Fehlermeldung aus ArcPy abrufen und entsprechend darauf reagieren. Wenn ein Skript über keine Fehlerbehandlungsroutine verfügt, schlägt seine Ausführung sofort fehl. Dies bedeutet natürlich, dass es weniger robust ist. Verwenden Sie daher Fehlerbehandlungsroutinen, um Fehler zu behandeln und die Verwendbarkeit von Skripten zu verbessern.
Fehlermeldungen der Geoverarbeitungswerkzeuge gehen mit einem sechsstelligen Code einher. Für diese ID-Codes gibt es Dokumentation, in der Sie weitere Informationen zu den Ursachen und zur Fehlerbehebung finden.
try-/except-Anweisung
In einer try-/except-Anweisung können ganze Programme oder bestimmte Codeabschnitte eingeschlossen werden, um Fehler abzufangen und zu identifizieren. Wenn innerhalb der try-Anweisung ein Fehler auftritt, wird eine Ausnahme ausgelöst, und der Code unter der except-Anweisung wird ausgeführt. Eine einfache except-Anweisung ist die einfachste Form der Fehlerbehandlung.
Im folgenden Code schlägt Puffer fehl, weil der erforderliche Parameter für die Entfernung nicht bereitgestellt wurde. Anstatt ohne Erläuterung fehlzuschlagen, wird der Fehler mit der except-Anweisung abgefangen, und die von Puffer erzeugte Fehlermeldung wird erfasst und ausgegeben. Beachten Sie, dass der except-Block nur ausgeführt wird, wenn Puffer einen Fehler zurückgibt.
import arcpy
try:
# Execute the Buffer tool
#
arcpy.Buffer_analysis("c:/transport/roads.shp", "c:/transport/roads_buffer.shp")
except Exception as e:
print e.message
# If using this code within a script tool, AddError can be used to return messages
# back to a script tool. If not, AddError will have no effect.
arcpy.AddError(e.message)
Die try-Anweisung weist eine optionale finally-Klausel auf. Diese kann für Vorgänge verwendet werden, die unabhängig davon, ob ein Fehler aufgetreten ist, immer ausgeführt werden sollen. Im folgenden Beispiel wird die Erweiterung Erweiterung "ArcGIS 3D Analyst" nach einer finally-Klausel wieder eingecheckt. Dadurch wird sichergestellt, dass die Erweiterung stets wieder eingecheckt wird.
class LicenseError(Exception):
pass
import arcpy
from arcpy import env
try:
if arcpy.CheckExtension("3D") == "Available":
arcpy.CheckOutExtension("3D")
else:
# Raise a custom exception
#
raise LicenseError
env.workspace = "D:/GrosMorne"
arcpy.HillShade_3d("WesternBrook", "westbrook_hill", 300)
arcpy.Aspect_3d("WesternBrook", "westbrook_aspect")
except LicenseError:
print "3D Analyst license is unavailable"
except:
print arcpy.GetMessages(2)
finally:
# Check in the 3D Analyst extension
#
arcpy.CheckInExtension("3D")
raise-Anweisung
Im oben gezeigten Beispiel wurde das Behandeln einer Ausnahme erläutert, die im Code aufgetreten ist. In einigen Fällen müssen Sie jedoch evtl. benutzerdefinierte Ausnahmen erstellen. Zu diesem Zweck kann eine raise-Anweisung verwendet werden. Im folgenden Codebeispiel wird eine raise-Anweisung verwendet, wenn eine Eingabe-Feature-Class festgestellt wurde, die keine Features enthält. Im engeren Sinne ist dies kein Fehler, sondern eine Bedingung, vor der der Code geschützt werden kann.
class NoFeatures(Exception):
pass
import arcpy
import os
arcpy.env.overwriteOutput = 1
fc = arcpy.GetParameterAsText(0)
try:
# Check that the input has features
#
result = arcpy.GetCount_management(fc)
if int(result.getOutput(0)) > 0:
arcpy.FeatureToPolygon_management(fc, os.path.dirname(fc) + os.sep + "out_poly.shp")
else:
# Raise custom exception
#
raise NoFeatures(result)
except NoFeatures:
# The input has no features
#
print fc + " has no features."
except:
# By default any other errors will be caught here
#
print arcpy.GetMessages(2)
ExecuteError-Klasse
Wenn ein Geoverarbeitungswerkzeug fehlschlägt, löst es eine ExecuteError-Ausnahmeklasse aus. Dies bedeutet, dass Sie Fehler in zwei Gruppen unterteilen können: Geoverarbeitungsfehler (die eine ExecuteError-Ausnahme auslösen) und alle anderen Fehler. Sie können die Fehler wie im Code unten gezeigt dann jeweils unterschiedlich behandeln:
import arcpy
try:
result = arcpy.GetCount_management("C:/invalid.shp")
# Return geoprocessing specific errors
#
except arcpy.ExecuteError:
arcpy.AddError(arcpy.GetMessages(2))
# Return any other type of error
except:
arcpy.AddError("Non-tool error occurred")
Traceback
In umfangreichen, komplexen Skripten kann die genaue Position eines Fehlers möglicherweise nur schwer bestimmt werden. Mit den Python-Modulen sys und traceback können die genaue Position und die Ursache des Fehlers ermittelt werden. Dabei wird die Ursache eines Fehlers genauer bestimmt, und Sie sparen wertvolle Zeit bei der Fehlerbehebung.
# Import the required modules
#
import arcpy
import sys
import traceback
arcpy.env.workspace = "C:/Data/myData.gdb"
try:
arcpy.CreateSpatialReference_management()
#--------------------------
# Your code goes here
#
# See the table below for examples
#--------------------------
except arcpy.ExecuteError:
# Get the tool error messages
#
msgs = arcpy.GetMessages(2)
# Return tool error messages for use with a script tool
#
arcpy.AddError(msgs)
# Print tool error messages for use in Python/PythonWin
#
print msgs
except:
# Get the traceback object
#
tb = sys.exc_info()[2]
tbinfo = traceback.format_tb(tb)[0]
# Concatenate information together concerning the error into a message string
#
pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
# Return python error messages for use in script tool or Python Window
#
arcpy.AddError(pymsg)
arcpy.AddError(msgs)
# Print Python error messages for use in Python / Python Window
#
print pymsg + "\n"
print msgs
Wenn Sie den oben gezeigten Code verwenden und dabei ein Fehler des Geoverarbeitungswerkzeugs (wie etwa eine ungültige Eingabe) auftritt, wird die ExecuteError-Ausnahme ausgelöst und die erste except-Anweisung verwendet. Diese Anweisung gibt die Fehlermeldungen dann mithilfe der Funktion GetMessages aus. Tritt bei demselben Code eine andere Art von Fehler auf, wird die zweite except-Anweisung verwendet. In diesem Fall werden nicht die Geoverarbeitungsmeldungen ausgegeben, sondern es wird ein traceback-Objekt abgerufen, und die entsprechenden Systemfehlermeldungen werden ausgegeben.
Die folgende Tabelle enthält die erwarteten Fehler aus drei unterschiedlichen Codezeilen, die in den obigen Code eingefügt werden könnten. Der erste Fehler ist ein Fehler des Geoverarbeitungswerkzeugs, bei dem die traceback-Informationen und die Fehlermeldungen der Geoverarbeitung ausgegeben werden. Der zweite und dritte Fehler wird nicht speziell abgefangen, und es werden nur die traceback-Informationen ausgegeben.
Ihr Code |
Fehler |
---|---|
arcpy.GetCount_management("") |
|
x = "a" + 1 |
|
float("Textzeichenfolge") |
|
Abrufen von Fehlermeldungen aus einem Ergebnisobjekt
Eine kurze Anmerkung zum unten dargestellten Ergebnisobjekt:
result = arcpy.GetCount_management("c:/data/rivers.shp")
Wenn der Aufruf zu GetCount eine Ausnahme auslöst, wird das Ergebnisobjekt auf Null gesetzt. Dies bedeutet, dass Sie keine Fehlermeldungen aus dem Ergebnisobjekt abrufen können.
import arcpy
try:
result = arcpy.GetCount_management("c:/data/rivers.shp")
# Return GEOPROCESSING specific errors
# (this method is INCORRECT!)
except:
arcpy.AddError(result.getMessages(2))
Der oben gezeigte Code schlägt fehl und es wird die Meldung "Name 'Ergebnis' ist nicht definiert" angezeigt. Das liegt daran, dass das Ergebnisobjekt aufgrund des fehlgeschlagenen Werkzeugs nicht erstellt werden konnte. Da das Ergebnisobjekt nicht erstellt wird, wird beim Versuch, die getMessages-Methode zu verwenden, ein Python-Fehler ausgelöst.
Ein Ergebnisobjekt, das durch den Aufruf eines Geoverarbeitungs-Service auf ArcGIS for Server erstellt wurde, wird auch bei Fehlschlagen eines Werkzeugs erstellt. Ein Ergebnisobjekt wird nur dann nicht erstellt, wenn ein Werkzeug lokal ausgeführt wird und einen Fehler auslöst. Weitere Informationen zur Verwendung des Ergebnisobjekts finden Sie im Abschnitt Abrufen von Ergebnissen aus einem Geoverarbeitungswerkzeug.