Depurar una clase ToolValidator
Como se muestra a continuación, para programar una clase ToolValidator, haga clic con el botón derecho del ratón en la herramienta, haga clic en Propiedades, haga clic en la ficha Validación y después haga clic en Editar. Esto abre el editor de Python Instalado, como IDLE o PythonWin. Agregue el código, guarde los cambios, salga del editor y después haga clic en Aplicar o en Aceptar en el panel de validación.
Cuando hace clic en Aplicar o en Aceptar, se verifica si existen errores de sintaxis en el código ToolValidator. Si existen errores de sintaxis en algunos de los métodos de clase, aparece un cuadro de mensaje que incluye una descripción del error de sintaxis el cual debe solucionar antes de aplicar la edición. Además de verificar si existen errores de sintaxis, se inicia la clase ToolValidator, se invoca el método initializeParameters y se verifica si tiene errores de ejecución. Un ejemplo de error de tiempo de ejecución es la invocación de un método que no existe, como el siguiente:
fc = self.params[0].Value # Should be "value"
Los errores de tiempo de ejecución en los métodos updateParameters y updateMessages se encuentran cuando se abre el cuadro de diálogo de la herramienta y se invocan los métodos. Los errores de tiempo de ejecución se muestran como errores en el primer parámetro. Esto se muestra a continuación; el método updateParameters contiene un error de escritura (por ejemplo, Valor versus valor):
Para ejecutar la herramienta, debe editar el código ToolValidator y solucionar el error (en este caso, cambiar Valor por valor).
Utilizar la función Describir
Un tema imperceptible pero importante es el uso de la función Describir.
Cuando utilice la función Describir, nunca utilice la representación de cadena de texto del valor.
Incorrecto (se utiliza la función de cadena de texto)
desc = arcpy.Describe(str(self.params[0].value))
Correcto
desc = arcpy.Describe(self.params[0].value)
No debe utilizar la representación de cadenas de caracteres para los datasets (que genera la ruta del catálogo hacia el dataset) porque es posible que el dataset no exista —tal vez, es una variable derivada del modelo el cual se debe ejecutar antes de que exista un dataset en el disco. (Puede comprobar si un parámetro incluye una variable derivada con el método parameter.isInputValueDerived.) Si utiliza la representación de cadena de texto para el dataset, la función Describir puede fallar ya que es posible que aún no exista el dataset en el disco.
Asegurarse de que el parámetro tenga un valor antes de la prueba
Un error común de codificación de ToolValidator es no comprobar si existen valores no iniciados.
Incorrecto (El valor no está establecido y hay un error en arcpy.Describe.)
fc = self.params[0].value shapetype = arcpy.Describe(fc).shapeType.lower()
Correcto (Comprobar que existe un valor en primer lugar.)
fc = self.params[0].value if fc: shapetype = arcpy.Describe(fc).shapeType.lower()
Depuración avanzada
Aún cuando la clase ToolValidator no tenga errores de sintaxis ni de tiempo de ejecución, pueden existir errores de lógica, tales como la incorrecta habilitación o deshabilitación de parámetros, errores en el cálculo de los valores predeterminados o errores al completar la descripción de salida. Tradicionalmente, existen dos técnicas para encontrar errores de lógica en una herramienta de secuencia de comandos:
- Imprimir los mensajes de depuración utilizando la directiva de impresión o la función de geoprocesamiento AddMessage.
- Recorrer el código en un depurador.
Debido a que el código ToolValidator está almacenado junto con la herramienta y se ejecuta sólo cuando se utiliza el cuadro de diálogo o la línea de comandos, estas dos técnicas requieren un manejo especial en ToolValidator.
Mostrar mensajes de depuración
Desafortunadamente, no se pueden imprimir mensajes en ToolValidator —la directiva de impresión de Python no tiene efecto debido a que no existe un lugar para escribir el mensaje. Utilizar los métodos de parámetro de objeto setErrorMessage y setWarningMessage para mostrar los mensajes de depuración es problemático, sólo los puede utilizar en el método updateMessages, pero es probable que el método de depuración que desea mostrar se haya generado en updateParameters, y no hay una manera de pasar los mensajes de depuración de un método de clase a otro en ToolValidator.
Sin embargo, puede utilizar el siguiente truco:
- Agregue un nuevo parámetro de cadena de texto a la herramienta. Colóquelo en la última posición.
- En updateParameters, escriba el mensaje de depuración para este nuevo parámetro.
- Abra el cuadro de diálogo de la herramienta y proporcione los valores. El mensaje de depuración aparece en el nuevo parámetro de cadena de texto.
- Después de encontrar y de solucionar el tema, quite el último parámetro de la lista de parámetros y sus usos en el código ToolValidator.
El siguiente código lo demuestra:
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
Depurar en un IDE de Python
En algunos casos, imprimir los mensajes de depuración no es suficiente y debe depurar el código mediante el uso de un IDE de Python (como IDLE o PythonWin), la configuración de puntos de corte, el recorrido del código, el examen de los valores y la solución de los errores de lógica.
Para depurar, cree una secuencia de comandos independiente y depúrela dentro del editor. En la parte superior de la secuencia de comandos, cargue la caja de herramientas, cree el conjunto de parámetros y a continuación establezca los valores de parámetro necesarios, de la siguiente manera:
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"
Observe que arcpy.GetParameterInfo contiene el nombre de la herramienta, no la etiqueta. Esto permite que el geoprocesamiento cree el conjunto de parámetros. Después, establezca uno o más parámetros del conjunto.
Ahora, agregue el código ToolValidator. (Puede copiar y pegar el código directamente desde el cuadro de diálogo Propiedades).
En la parte inferior de la secuencia de comandos, llame a ToolValidator de la siguiente manera:
# Create the ToolValidator class and call updateParameters # and/or updateMessages # validator = ToolValidator() validator.updateParameters()
Para revisar, la estructura básica de la secuencia de comandos independiente es la siguiente (el código ToolValidator real se quitó para que el ejemplo sea breve):
# 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()