Como ignorar erros no loop for / while do arcpy?

10

Eu tenho uma ferramenta de script útil que percorre um espaço de trabalho e renomeia e copia os shapefiles para um conjunto de dados de recursos. No entanto, se houver um shapefile corrompido em algum lugar da área de trabalho, o script falhará e interromperá o processamento.

Como você lida com erros como esse? Existe uma maneira de imprimir o arquivo de erro e continuar processando o próximo shapefile no loop for até a conclusão?

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()
Aaron
fonte

Respostas:

15

Tente pesquisar no Google por "python em erro ao continuar" ou semelhante. Isso retorna um número de hits, incluindo este do StackOverflow :

Se você souber quais instruções podem falhar e como elas podem falhar, use o tratamento de exceções para limpar especificamente os problemas que podem ocorrer com um bloco específico de instruções antes de passar para a próxima seção.

1) Uma opção pode ser colocar um try...exceptbloco ao redor da linha que você suspeita que causará o problema, ou seja, a ferramenta CopyFeatures.

2) Veja também a referência do Python sobre erros , especificamente a seção 8.3. Depois de ter uma referência a "e", você poderá determinar seu tipo de exceção e manipulá-lo conforme necessário.

Por exemplo, esta pergunta StackOverflow contém um fluxo de trabalho semelhante ao seu:

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"

No seu caso, no lugar de "IndexError", você usaria o que determinasse como o tipo de exceção para um shapefile corrompido

Stephen Lead
fonte
1
Você também pode tentar adicionar seu nome shp à lista de erros na seção de exceção. Defina seu ie. ErrLst = [] antes do loop FOR e na linha de seção exceto antes de CONTINUE do ErrLst.append (shp). No final do programa, faça-- para l em ErrLst: print >> file.txt, l. Isso deve imprimir sua lista em um arquivo. Eu não testei, mas deveria funcionar.
Tomek
Obrigado Stephen, o bloco try / except-continue fará o truque.
Aaron
7

Como Stephen já disse, você pode colocar a ferramenta CopyFeatures em outra tentativa ... exceto em Block.

Se a ferramenta falhar com um Shapefile específico, você poderá registrar a Mensagem da Ferramenta em algum lugar (eu sempre a imprimo no STDOUT e canalizo as saídas para um arquivo de log quando executo o script).

O que tenho a acrescentar é: No Bloco Exceto, ao lado da Exceção, você também precisa imprimir as mensagens de erro que a própria Ferramenta produziu. Você não obtém acesso às mensagens da Ferramenta pela Exceção (como deve ser certo), mas pelo Objeto arqueado chamando

arcpy.getmessages(messageCount - 1)

Veja http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//000v0000000m000000 como chamá-lo e como obter as últimas mensagens possivelmente relacionadas ao erro específico do Shapefile.

Depois de registrar isso, você simplesmente deixa o script continuar com os outros shapefiles

Jürgen Zornig
fonte