Wie umgehe ich Fehler in der arcpy for / while-Schleife?

10

Ich habe ein praktisches Skript-Tool, das einen Arbeitsbereich durchläuft und Shapefiles umbenennt und in ein Feature-Dataset kopiert. Wenn sich jedoch irgendwo im Arbeitsbereich ein beschädigtes Shapefile befindet, schlägt das Skript fehl und beendet die Verarbeitung.

Wie gehen Sie mit solchen Fehlern um? Gibt es eine Möglichkeit, die Fehlerdatei zu drucken und die Verarbeitung des nächsten Shapefiles in der for-Schleife bis zum Abschluss fortzusetzen?

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
quelle

Antworten:

15

Versuchen Sie, nach "Python bei Fehler als nächstes fortzufahren" oder ähnlichem zu googeln. Dies gibt eine Reihe von Treffern zurück, einschließlich dieses von StackOverflow :

Wenn Sie wissen, welche Anweisungen möglicherweise fehlschlagen und wie sie fehlschlagen können, können Sie die Ausnahmebehandlung verwenden, um die Probleme, die bei einem bestimmten Anweisungsblock auftreten können, gezielt zu beheben, bevor Sie mit dem nächsten Abschnitt fortfahren.

1) Möglicherweise können Sie einen try...exceptBlock um die Linie setzen , von der Sie vermuten, dass sie das Problem verursacht, nämlich das CopyFeatures-Tool.

2) Siehe auch die Python-Referenz zu Fehlern , insbesondere Abschnitt 8.3. Sobald Sie einen Verweis auf "e" haben, können Sie möglicherweise den Ausnahmetyp bestimmen und ihn nach Bedarf behandeln.

ZB enthält diese StackOverflow- Frage einen ähnlichen Workflow wie Ihre:

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"

In Ihrem Fall würden Sie anstelle von "IndexError" den von Ihnen festgelegten Ausnahmetyp für ein beschädigtes Shapefile verwenden

Stephen Lead
quelle
1
Sie können auch versuchen, Ihren shp-Namen zur Fehlerliste im Ausnahmeabschnitt hinzuzufügen. Definieren Sie Ihre dh. ErrLst = [] vor der FOR-Schleife und in der Ausnahmeabschnittszeile vor CONTINUE ErrLst.append (shp). Am Ende des Programms do-- für l in ErrLst: print >> file.txt, l. Dies sollte Ihre Liste in eine Datei drucken. Ich habe es nicht getestet, sollte aber funktionieren.
Tomek
Danke Stephen, der Try / Except-Continue-Block wird den Trick machen.
Aaron
7

Wie Stephen bereits sagte, können Sie das CopyFeatures-Tool in einem anderen Versuch einschließen ... außer Block.

Wenn das Tool mit einer bestimmten Shapefile fehlschlägt, können Sie die Tool-Nachricht irgendwo protokollieren (ich drucke sie immer auf STDOUT und leite die Ausgaben an eine Logdatei weiter, wenn ich das Skript ausführe).

Was ich hinzufügen muss, ist: Im Ausnahmeblock neben der Ausnahme müssen Sie auch die Fehlermeldungen drucken, die das Tool selbst erstellt hat. Sie erhalten keinen Zugriff auf die Tool-Nachrichten über die Ausnahme (wie es sicher sein sollte), sondern über das arcpy-Objekt durch Aufrufen

arcpy.getmessages(messageCount - 1)

Unter http://help.arcgis.com/de/arcgisdesktop/10.0/help/index.html#//000v0000000m000000 erfahren Sie, wie Sie es aufrufen und die letzten Nachrichten abrufen, die möglicherweise mit dem spezifischen Shapefile-Fehler zusammenhängen.

Nachdem Sie dies protokolliert haben, lassen Sie das Skript einfach mit den anderen Shapefiles fortfahren

Jürgen Zornig
quelle