Ошибки случаются. Написание скриптов, которое предполагает наличие и обработку ошибок, сохраняет массу времени и ваших сил. Когда инструмент выводит сообщение об ошибке, ArcPy генерирует системную ошибку или исключение. В Python вы можете обеспечить различные структуры и методы для обработки исключений. Конечно, скрипт может не выполниться по причинам, не связанным с инструментом геообработки. Их также следует обнаружить и решить. В следующих разделах предлагается несколько способов, которые ознакомят вас с основными принципами обработки исключений в Python.
Когда инструмент записывает сообщение об ошибке, ArcPy создает исключение arcpy.ExecuteError. Python позволяет написать модуль, который будет выполняться автоматически при возникновении системной ошибки. С помощью этого модуля для обработки ошибок вы сможете получать сообщения об ошибках от ArcPy и реагировать на них. Если скрипт не имеет модуля для обработки ошибок, он завершает выполнение немедленно, что уменьшает его надежность. Модуль обработки ошибок можно использовать для управления ошибками и повышения надежности скриптов.
Сообщения об ошибках в инструментах геообработки обычно имеют шестизначный код. Эти коды-идентификаторы занесены в документы, содержащие дополнительные сведения об их причинах и необходимых действиях.
Выражение try-except
Чтобы охватить всю программу целиком или только отдельные фрагменты кода для обнаружения и определения ошибок могут использоваться выражения try-except. Если в выражении try возникнет ошибка, будет создано исключение, и код будет выполнен в соответствии с выражением except. Использование выражения except является наиболее простой формой обработки ошибок.
В следующем коде Буфер не работает, потому что не был указан обязательный аргумент buffer_distance_or_field. Чтобы найти ошибку, используется выражение except, которое извлекает и выводит сообщение об ошибке, сгенерированное Буфером. Обратите внимание, что блок except выполняется только в случае, если Буфер возвращает ошибку.
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])
Выражение try содержит необязательное условие finally, которое можно использовать для задач, которые должны выполняться всегда, независимо от того, возникает исключение или нет. В следующем примере ArcGIS 3D Analyst extension регистрируется в соответствии с условием finally, которое гарантирует, что этот дополнительный модуль всегда будет регистрироваться.
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
Предыдущий пример иллюстрирует ошибку в исключении, которое возникло в коде В некоторых случаях может потребоваться создать пользовательские исключения. Для этой цели может использоваться выражение raise. В следующем коде выражение raise используется, если входной класс объектов определился как не содержащий объектов. Это не обязательно ошибка, но условие, при котором код может быть использован.
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
Когда инструмент геообработки выходит из строя, он создает класс исключений arcpy.ExecuteError, что означает, что вы можете разделить ошибки на различные группы, ошибки геообработки (те, которые создают исключение arcpy.ExecuteError) и другие типы исключений. Затем можно обрабатывать эти ошибки по разному, как показано в следующем коде:
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
В больших и более сложных скриптах бывает сложно точное определить место возникновения ошибки. Для определения точного местоположения и причины ошибки, а также для более точного определения причины ошибки и экономии ценного времени на отладку можно использовать модули Python, sys и tracebackсовместно.
# 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)
Если был использован приведенный выше код, и произошла ошибка инструмента геообработки, такая как недопустимые входные данные, это вызовет arcpy.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_management вызывает исключение, объект Result не создается. Это означает, что вы не можете получать сообщения об ошибках от объекта Result.
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))
Указанный выше код не работает, и появляется сообщение name 'result' is not defined. Причина в том, что объект Result невозможно было создать из-за ошибки инструмента. Поскольку объект Result не создан, возникает ошибка Python при попытке использования метода getMessages.
Примечание:
Объект Result, создаваемый путем запроса в сервис геообработки на ArcGIS Server, создается даже при ошибке инструмента. Создание объекта Result не удается только тогда, когда инструмент запускается локально и вызывает ошибку. Более подробную информацию об использовании объекта result смотрите в разделе Использование инструментов в Python.