Jak ominąć błędy w arcpy dla pętli / while?

10

Mam przydatne narzędzie skryptowe, które przechodzi przez obszar roboczy, zmienia nazwy i kopiuje pliki kształtów do zestawu danych funkcji. Jeśli jednak gdzieś w obszarze roboczym znajduje się uszkodzony plik kształtu, skrypt nie działa i przestaje przetwarzać.

Jak radzisz sobie z takimi błędami? Czy istnieje sposób wydrukowania pliku błędu i kontynuowania przetwarzania następnego pliku shapefile w pętli for do zakończenia?

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
źródło

Odpowiedzi:

15

Spróbuj googling dla „python w przypadku wznowienia błędu dalej” lub podobny. Zwraca liczbę trafień, w tym tę z StackOverflow :

Jeśli wiesz, które instrukcje mogą się nie powieść i jak mogą się nie powieść, możesz skorzystać z obsługi wyjątków, aby w szczególności wyczyścić problemy, które mogą wystąpić w przypadku określonego bloku instrukcji, zanim przejdziesz do następnej sekcji.

1) try...exceptOpcją może być umieszczenie bloku wokół linii, co do której podejrzewasz, że spowoduje problem, a mianowicie narzędzie CopyFeatures.

2) Zobacz także odwołanie do błędów w Pythonie , w szczególności sekcja 8.3. Gdy znajdziesz już odniesienie do „e”, możesz określić jego wyjątek i odpowiednio go obsłużyć.

Na przykład to pytanie StackOverflow zawiera podobny przepływ pracy:

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"

W twoim przypadku zamiast „IndexError” użyłbyś wszystkiego, co określiłeś jako typ wyjątku dla uszkodzonego pliku kształtu

Stephen Lead
źródło
1
Możesz także spróbować dodać swoją nazwę shp do listy błędów w sekcji wyjątków. Zdefiniuj swój ie. ErrLst = [] przed pętlą FOR i w wierszu sekcji wyjątku przed KONTYNUUJ wykonaj ErrLst.append (shp). Na końcu programu wykonaj-- dla lw ErrLst: print >> file.txt, l. To powinno wydrukować listę do pliku. Nie przetestowałem tego, ale powinno działać.
Tomek
Dzięki Stephen, blok try / wyjątkiem-kontynuacji załatwi sprawę.
Aaron
7

Jak już powiedział Stephen, możesz dołączyć narzędzie CopyFeatures do innej próby ... oprócz Block.

Jeśli narzędzie zawiedzie z określonym plikiem Shapefile, możesz gdzieś zapisać komunikat narzędzia (zawsze drukuję go na STDOUT i przesyłam dane wyjściowe do pliku dziennika po uruchomieniu skryptu).

Muszę dodać: W bloku z wyjątkiem wyjątku musisz również wydrukować komunikaty o błędach wygenerowane przez samo narzędzie. Nie uzyskujesz dostępu do komunikatów Narzędzi na podstawie wyjątku (jak powinno być na pewno), ale z arkadowego obiektu poprzez wywołanie

arcpy.getmessages(messageCount - 1)

Zobacz http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//000v0000000m000000, jak to wywołać i jak uzyskać ostatnie wiadomości, które są prawdopodobnie związane z konkretnym błędem kształtu pliku.

Po zalogowaniu możesz po prostu pozwolić skryptowi kontynuować pracę z innymi plikami kształtowymi

Jürgen Zornig
źródło