Обработка ошибок с помощью Python
Ошибки случаются. Написание скриптов, которое предполагает наличие и обработку ошибок, сохраняет массу времени и сил. Когда инструмент выводит сообщение об ошибке, ArcPy генерирует системную ошибку или исключение. В Python вы можете обеспечить различные структуры и методы для обработки исключений. Конечно, скрипт может завершить работу по иным причинам, которые не обязательно относятся к инструменту геообработки; такие ситуации должны быть замечены и обработаны нужным образом. В следующих разделах предлагаются несколько методов, которые знакомят вас с основами обработки исключений в Python.
Когда инструмент записывает сообщение об ошибке, ArcPy создает системную ошибку или исключение. Python позволяет написать модуль, который запускается автоматически при возникновении системной ошибки. С помощью этого модуля для обработки ошибок вы можете получать сообщения об ошибках от ArcPy и реагировать на них. Если скрипт не имеет модуля для обработки ошибок, он завершает выполнение немедленно, что уменьшает его надежность. Модуль обработки ошибок можно использовать для управления ошибками и повышения надежности скриптов.
Сообщения об ошибках в инструментах геообработки обычно имеют шестизначный код. Эти коды-идентификаторы занесены в документы, содержащие дополнительные сведения об их причинах и необходимых действиях.
Выражение try-except
Выражение try-except может быть использовано для разделения программы на шаги, чтобы контролировать выполнение каждого из них и определять места возникновения ошибок. Если ошибка случается внутри выражения try, вызывается исключение и выполняется код в выражении except. Использование выражения except является наиболее простой формой обработки ошибок.
В следующем коде Буфер прекращает работу из-за того, что не был указан требуемый параметр Расстояние (Distance). Вместо завершения без объяснения причин, выражение except используется для поиска ошибки, ее перехвата и вывода сообщения об ошибке, созданной инструментом Буфер. Обратите внимание, что блок except выполняется только в случае, если в инструменте Буфер происходит ошибка.
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)
Выражение try имеет опциональный оператор finally, использующийся для задач, которые должны выполняться в любом случае, вне зависимости от появления исключения. В следующем примере, дополнительный модуль Дополнительный модуль ArcGIS 3D Analyst включается в оператор finally, что обеспечивает постоянное включение расширения.
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
В предыдущем примере обрабатывается ошибка, произошедшая в коде; в некоторых случаях может быть необходимо создание собственного исключения. Для этой цели может быть использовано выражение raise. В следующем коде выражение raise используется, когда входной класс пространственных объектов определяется как не содержащий объектов. Это не обязательно ошибка, но условие, при котором код может быть использован.
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
Если инструмент геообработки прекращает работу, он генерирует класс исключений ExecuteError. Это означает, что можно разделить ошибки на две группы, ошибки геообработки (которые вызывают исключение ExecuteError) и все остальные. Затем можно обрабатывать эти ошибки по разному, как показано в следующем коде:
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")
отслеживание
В больших и более сложных скриптах бывает сложно точное определить место возникновения ошибки. Модули sys и traceback в Python могут быть использованы вместе для определения точного расположения и причины появления ошибки, определения самой ошибки более точным образом и экономят время при отладке скрипта.
# 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
Если вышеуказанный код будет использован, и в нем возникнет ошибка геообработки, такая как некорректные входные данные, это вызовет ExecuteError, и будет использовано первое выражение except. Это выражение выведет сообщение об ошибке с помощью функции GetMessages. Если в коде возникнет ошибка другого типа, будет использовано второе выражение except. Вместо вывода сообщения о процессе геообработки будет получен объект traceback и выведено подходящее сообщение о соответствующей системной ошибке.
В таблице ниже показаны ожидаемые ошибки, являющиеся результатом трех различных строк кода, который мог быть использован вместо вышеуказанного кода. Первый пример - ошибка инструмента геообработки, которая генерирует информацию traceback и сообщения об ошибках геообработки. Второй и третий примеры не обрабатываются, происходит только генерация данных traceback.
Ваш код |
Результирующая ошибка |
---|---|
arcpy.GetCount_management("") |
|
x = "a" + 1 |
|
float("a text string") |
|
Получение сообщений об ошибках от объекта Result
Краткая информация об объекте Result, показанном ниже:
result = arcpy.GetCount_management("c:/data/rivers.shp")
Если при вызове GetCount выдается исключение, объект result имеет нулевое значение. Это означает, что вы не сможете получать сообщения об ошибках от объекта result.
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))
Вышеуказанный код выдает сообщение об ошибке "name 'result' is not defined". Это связано с тем, что объект result не создается из-за ошибки инструмента. Поскольку объект result не создается, при попытке использования метода getMessages возникает ошибка Python.
Объект result, создаваемый посредством службы геообработки в ArcGIS for Server, создается даже при ошибке инструмента. Объект result не создается только тогда, когда инструмент запускается локально и выдает ошибку. Более подробную информацию об использовании объекта result смотрите в разделе Получение результатов инструмента геообработки.