Как обойти ошибки в arcpy для цикла / while?

10

У меня есть удобный инструмент-скрипт, который перебирает рабочее пространство, переименовывает и копирует шейп-файлы в набор классов объектов. Однако если где-то в рабочей области есть поврежденный шейп-файл, сценарий завершается ошибкой и останавливает обработку.

Как вы справляетесь с такими ошибками? Есть ли способ напечатать файл ошибок и продолжить обработку следующего шейп-файла в цикле for до завершения?

import arcpy
from arcpy import env

# Allow overwriting of output  
env.overwriteOutput = True

# Parameters  
env.workspace = arcpy.GetParameterAsText(0) 
state = arcpy.GetParameterAsText(1)
gdb = arcpy.GetParameterAsText(2)

# Get a list of shapefiles in folder  
fcs = arcpy.ListFeatureClasses() 

# Find the total count of shapefiles in list  
fcCount = len(fcs) 

# Set the progressor 
arcpy.SetProgressor("step", "Copying shapefiles to geodatabase...", 0,fcCount, 1) 

# For each shapefile, copy to a file geodatabase

try:
    for shp in fcs: 


        # Define name for the output points 
        fc = str(state + shp[0:9])

        # Update the progressor label for current shapefile  
        arcpy.SetProgressorLabel("Loading " + shp + "...") 

        # Copy the data  
        arcpy.CopyFeatures_management(shp, str(gdb + "\\" + fc)) 

        # Update the progressor position  
        arcpy.SetProgressorPosition()

except Exception as e:
    print "An error has occurred"
    print e

arcpy.ResetProgressor()
Аарон
источник

Ответы:

15

Попробуйте Googling для «Python при ошибке возобновить следующий» или аналогичный. Это возвращает количество попаданий, включая этот из StackOverflow :

Если вы знаете, какие операторы могут потерпеть неудачу и как они могут потерпеть неудачу, то вы можете использовать обработку исключений, чтобы специально устранить проблемы, которые могут возникнуть с определенным блоком операторов, прежде чем переходить к следующему разделу.

1) Опция может заключаться в том, чтобы поместить try...exceptблок вокруг линии, которая, как вы подозреваете, вызовет проблему, а именно - инструмент CopyFeatures.

2) См. Также ссылку Python на ошибки , в частности, раздел 8.3. Получив ссылку на «e», вы сможете определить тип исключения и обработать его по мере необходимости.

Например, этот вопрос StackOverflow содержит рабочий процесс, аналогичный вашему:

for getter in (get_random_foo, get_random_bar):
    try:
        return getter()
    except IndexError:
        continue  # Ignore the exception and try the next type.

raise IndexError, "No foos, no bars"

В вашем случае вместо «IndexError» вы будете использовать любой тип исключения для поврежденного шейп-файла.

Стивен Лид
источник
1
Вы также можете попробовать добавить свое имя shp в список ошибок в разделе исключений. Определите свой т.е. ErrLst = [] перед циклом FOR и в строке раздела кроме перед CONTINUE выполните ErrLst.append (shp). В конце программы do-- for l в ErrLst: print >> file.txt, l. Это должно напечатать ваш список в файл. Я не проверял это, но должно работать.
Томек
Спасибо Стивену, блок try / exception-continue сделает свое дело.
Аарон
7

Как уже сказал Стивен, вы можете заключить инструмент CopyFeatures в другую попытку ... кроме блока.

Если инструмент не работает с определенным шейп-файлом, вы можете где-нибудь записать сообщение об инструменте (я всегда печатаю его в STDOUT и отправляю выходные данные в лог-файл, когда запускаю скрипт).

Я должен добавить следующее: в блоке исключений рядом с исключением, вы также должны распечатать сообщения об ошибках, выданные самим инструментом. Вы не получаете доступ к сообщениям Tool через Исключение (как это должно быть наверняка), но из arcpy Object, вызывая

arcpy.getmessages(messageCount - 1)

См. Http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//000v0000000m000000 как его вызвать и как получить последние сообщения, которые, возможно, связаны с конкретной ошибкой шейп-файла.

После регистрации вы просто позволяете сценарию продолжить работу с другими шейп-файлами.

Юрген Цорниг
источник