Fehler sind nicht immer zu vermeiden. Wenn Sie Skripte erstellen, die auf Fehler vorbereitet sind und darauf reagieren können, sparen Sie sich 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 eine arcpy.ExecuteError-Ausnahme. Mit Python können Sie eine Routine schreiben, die bei jedem Systemfehler automatisch ausgeführt wird. In dieser Fehlerverarbeitungsroutine rufen Sie die Fehlermeldung aus ArcPy ab und reagieren entsprechend darauf. 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 erkennen und die Verwendbarkeit von Skripten zu verbessern.
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 das erforderliche buffer_distance_or_field-Argument nicht bereitgestellt wurde. Anstatt ohne Erklärung 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
import sys
try:
# Execute the Buffer tool
arcpy.Buffer_analysis("c:/transport/roads.shp", "c:/transport/roads_buffer.shp")
except Exception:
e = sys.exc_info()[1]
print(e.args[0])
# 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.args[0])
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 ArcGIS 3D Analyst extension nach einer finally-Klausel wieder eingecheckt. Dadurch wird sichergestellt, dass die Erweiterung stets wieder eingecheckt wird.
class LicenseError(Exception):
pass
import arcpy
try:
if arcpy.CheckExtension("3D") == "Available":
arcpy.CheckOutExtension("3D")
else:
# Raise a custom exception
raise LicenseError
arcpy.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 arcpy.ExecuteError:
print(arcpy.GetMessages(2))
finally:
# Check in the 3D Analyst extension
arcpy.CheckInExtension("3D")
raise-Anweisung
Im oben gezeigten Beispiel wird eine Ausnahme erläutert, die im Code aufgetreten ist. In einigen Fällen müssen möglicherweise benutzerdefinierte Ausnahmen erstellt werden. 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. Der Code lässt sich einsetzen, um das Eintreffen dieser Bedingung zu vermeiden.
class NoFeatures(Exception):
pass
import arcpy
import os
import sys
arcpy.env.overwriteOutput = True
fc = arcpy.GetParameterAsText(0)
try:
# Check that the input has features
result = arcpy.GetCount_management(fc)
if int(result[0]) > 0:
arcpy.FeatureToPolygon_management(
fc, os.path.join(os.path.dirname(fc), 'out_poly.shp'))
else:
# Raise custom exception
raise NoFeatures(result)
except NoFeatures:
# The input has no features
print('{} has no features'.format(fc))
except:
# By default any other errors will be caught here
e = sys.exc_info()[1]
print(e.args[0])
ExecuteError-Klasse
Wenn ein Geoverarbeitungswerkzeug fehlschlägt, löst es eine arcpy.ExecuteError-Ausnahmeklasse aus. Dies bedeutet, dass Sie Fehler in zwei Gruppen unterteilen können: Geoverarbeitungsfehler (die eine arcpy.ExecuteError-Ausnahme auflösen) und andere Ausnahmetypen. Sie können die Fehler wie im Code unten gezeigt dann jeweils unterschiedlich behandeln:
import arcpy
import sys
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:
# By default any other errors will be caught here
e = sys.exc_info()[1]
print(e.args[0])
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 es kann wertvolle Zeit bei der Fehlerbehebung gespart werden.
# 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
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)
print(msgs)
Wenn Sie den oben gezeigten Code verwenden und dabei ein Fehler des Geoverarbeitungswerkzeugs (wie etwa eine ungültige Eingabe) auftritt, wird die arcpy.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 gedruckt.
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("a text string") |
|
Abrufen von Fehlermeldungen aus einem Ergebnisobjekt
Eine kurze Anmerkung zum unten dargestellten Result-Objekt:
result = arcpy.GetCount_management("c:/data/rivers.shp")
Wenn der Aufruf zu GetCount_management eine Ausnahme auslöst, wird das Result-Objekt nicht erstellt. Dies bedeutet, dass Sie keine Fehlermeldungen aus dem Result-Objekt abrufen können.
import arcpy
try:
result = arcpy.GetCount_management("c:/data/rivers.shp")
# Return Geoprocessing specific errors
# (this method is incorrect!)
except arcpy.ExecuteError:
arcpy.AddError(result.getMessages(2))
Der oben gezeigte Code schlägt fehl und es wird die Meldung name 'result' is not defined angezeigt. Das liegt daran, dass das Result-Objekt aufgrund des fehlgeschlagenen Werkzeugs nicht erstellt werden konnte. Da das Result-Objekt nicht erstellt wird, wird beim Versuch, die getMessages-Methode zu verwenden, ein Python-Fehler ausgelöst.