Debuggen einer ToolValidator-Klasse

Zum Programmieren einer ToolValidator-Klasse klicken Sie wie unten gezeigt mit der rechten Maustaste auf das Werkzeug und wählen dann zuerst Eigenschaften, dann die Registerkarte Validierung und abschließend die Option Bearbeiten aus. Hierdurch wird der installierte Python-Editor, etwa IDLE oder PythonWin, geöffnet. Fügen Sie Code hinzu, speichern Sie die Änderungen, beenden Sie den Editor, und klicken Sie im Fenster "Validierung" auf Übernehmen oder auf OK.

Eingeben von ToolValidator-Code

Wenn Sie auf Übernehmen oder OK klicken, wird der ToolValidator-Code auf Syntaxfehler überprüft. Falls in einer Klassenmethode Syntaxfehler vorliegen, wird eine Meldung mit einer Beschreibung des Syntaxfehlers angezeigt. Sie müssen den Fehler beheben, bevor Sie die Änderungen übernehmen können. Neben der Prüfung auf Syntaxfehler wird die ToolValidator-Klasse initialisiert, und die Methode initializeParameters wird aufgerufen und auf Laufzeitfehler überprüft. Ein Beispiel für einen Laufzeitfehler wäre der Aufruf einer nicht vorhandenen Methode, wie in der folgenden Codezeile:

fc = self.params[0].Value  # Should be "value"

Laufzeitfehler in den Methoden updateParameters und updateMessages werden erkannt, wenn das Werkzeugdialogfeld geöffnet wird und diese Methoden aufgerufen werden. Laufzeitfehler werden als Fehler im ersten Parameter angezeigt. Dies ist in der folgenden Abbildung zu sehen, in der die Methode updateParameters einen Rechtschreibfehler enthält (Value müsste value heißen):

Anzeige von Laufzeitfehlern

Um das Werkzeug ausführen zu können, müssen Sie den ToolValidator-Code bearbeiten und den Fehler beheben (das heißt in diesem Fall, Value in value ändern).

Verwenden der Funktion "Describe"

Wichtig ist die korrekte Verwendung der Funktion "Describe".

VorsichtVorsicht:

Verwenden Sie bei der Funktion "Describe" niemals die Zeichenfolgendarstellung des Wertes.

Falsch (Verwendung der str-Funktion)

  desc = arcpy.Describe(str(self.params[0].value))

Richtig

  desc = arcpy.Describe(self.params[0].value)

Verwenden Sie nicht die Zeichenfolgendarstellung für Datasets (die den Katalogpfad zum Dataset liefert), da das Dataset möglicherweise nicht vorhanden ist. Es könnte sich um eine von einem Modell abgeleitete Variable handeln, und das Modell muss ausgeführt werden, bevor das Dataset auf dem Datenträger vorhanden ist. (Sie können mit der parameter.isInputValueDerived-Methode überprüfen, ob ein Parameter eine abgeleitete Variable enthält.) Falls Sie die Zeichenfolgendarstellung für das Dataset verwenden, schlägt die Describe-Methode fehl, wenn das Dataset noch nicht auf dem Datenträger vorhanden ist.

Vergewissern Sie sich vor dem Test, dass der Parameter über einen Wert verfügt

Häufig wird bei der ToolValidator-Programmierung nicht überprüft, ob nicht initialisierte Werte vorliegen.

Falsch (Der Wert ist nicht festgelegt, und "arcpy.describe" schlägt fehl.)

  fc = self.params[0].value
  shapetype = arcpy.Describe(fc).shapeType.lower()

Richtig (Zuerst wird der Wert überprüft.)

  fc = self.params[0].value
  if fc:
    shapetype = arcpy.Describe(fc).shapeType.lower()

Komplexes Debuggen

Selbst wenn die ToolValidator-Klasse keine Syntax- und Laufzeitfehler aufweist, können einem bei der Programmierung logische Fehler unterlaufen, wie etwa nicht richtig aktivierte bzw. deaktivierte Parameter, falsch berechnete Standardwerte oder eine nicht ordnungsgemäß gefüllte Ausgabebeschreibung. Logische Fehler in einem Skriptwerkzeug können in der Regel auf zweierlei Weise ermittelt werden:

Da der ToolValidator-Code mit dem Werkzeug gespeichert und nur ausgeführt wird, wenn das Dialogfeld oder die Befehlszeile verwendet wird, erfordern diese beiden Vorgehensweisen eine bestimmte Verarbeitung in ToolValidator.

Anzeigen von Debugging-Meldungen

Meldungen können nicht in ToolValidator ausgegeben werden. Die Python-Druckdirektive "print" zeigt keine Wirkung, da es kein Ziel für die Meldung gibt. Die Anzeige von Debugging-Meldungen mit den Parameterobjektmethoden SetErrorMessage und SetWarningMessage ist problematisch. Sie können diese Methoden nur in der Methode updateMessages verwenden, die anzuzeigende Debugging-Meldung wurde jedoch sehr wahrscheinlich in der Methode updateParameters erzeugt. In ToolValidator können Debugging-Meldungen jedoch nicht zwischen Klassenmethoden ausgetauscht werden.

Sie können allerdings folgenden Trick verwenden:

  • Fügen Sie Ihrem Werkzeug einen neuen Zeichenfolgenparameter hinzu. Setzen Sie diesen Parameter an die letzte Stelle.
  • Schreiben Sie in updateParameters die Debugging-Meldung in diesen neuen Parameter.
  • Öffnen Sie das Werkzeugdialogfeld, und stellen Sie Werte bereit. Die Debugging-Meldung wird im neuen Zeichenfolgenparameter angezeigt.
  • Nachdem Sie den Fehler gefunden und behoben haben, löschen Sie den letzten Parameter aus der Parameterliste. Achten Sie darauf, dass er nirgendwo mehr im ToolValidator-Code verwendet wird.

Dies wird im folgenden Codeausschnitt gezeigt:

  def updateParameters(self):
    if self.params[0].value and not self.params[1].altered:
      desc = arcpy.Describe(self.params[0].value)
      fields = desc.fields
      for field in fields:
        fType = field.type.lower()
        if fType == "smallinteger" or \
           fType == "integer":
          self.params[1].value = field.name

          # Update our "debug" parameter to show
          #  the field type
          #
          self.params[2].value = fType
          break

        # No field, update "debug" parameter
        #
        self.params[1].value = ""
        self.params[2].value = "No field found"
    return

Debuggen in einer Python-IDE

Manchmal reicht es nicht, Debugging-Meldungen auszugeben. Dann müssen Sie Ihren Code in einer Python-IDE wie IDLE oder PythonWin debuggen, Haltepunkte festlegen, den Code schrittweise durchlaufen, die Werte untersuchen und logische Fehler beheben.

Erstellen Sie zum Debuggen ein eigenständiges Skript, und debuggen Sie es im Editor. Laden Sie zu Beginn des Skriptes die Toolbox, erstellen Sie ein Parameter-Array, und legen Sie dann die erforderlichen Parameterwerte wie folgt fest:

import arcpy

# Load the toolbox and get the tool's parameters, using the tool
#  name (not the tool label).
#
arcpy.ImportToolbox("E:/Documents/Tool Validation Examples.tbx")
params = arcpy.GetParameterInfo("HotSpots_stats")

# Set required parameters
#
params[0].value = "D:/st_johns/city.mdb/roads"

Beachten Sie, dass arcpy.GetParameterInfo den Namen des Werkzeugs, nicht die Beschriftung enthält. So kann die Geoverarbeitung das Parameter-Array für Sie erstellen. Sie legen dann einen oder mehrere Parameter im Array fest.

Jetzt fügen Sie den ToolValidator-Code hinzu. (Sie können den Code im Dialogfeld "Eigenschaften" kopieren und direkt einfügen.)

Rufen Sie ToolValidator am Ende des Skriptes wie folgt auf:

# Create the ToolValidator class and call updateParameters 
#   and/or updateMessages
#
validator = ToolValidator()
validator.updateParameters()

Die Grundstruktur des eigenständigen Skriptes ist also wie folgt (aus Gründen der Übersichtlichkeit ohne den eigentlichen ToolValidator-Code):

# Create the parameter array and values
#
import arcpy

# Add the toolbox and fetch the parameter list
#
arcpy.ImportToolbox("E:/Documents/Tool Validation Examples.tbx")
params = arcpy.GetParameterInfo("HotSpots_stats")
params[0].value = "D:/st_johns/city.mdb/roads"

# ToolValidator class block
#
class ToolValidator:

  def __init__(self):
    import arcpy 
    self.params = arcpy.GetParameterInfo()

  def initializeParameters(self):
    # (initializeParameters code here)
    return

  def updateParameters(self):
    # (updateParameters code here)
    return

  def updateMessages(self):
    # (updateMessages code here)
    return

# Call routine(s) to debug
#
validator = ToolValidator()
validator.updateParameters()
validator.updateMessages()

7/10/2012