Personalizar el comportamiento de una herramienta de secuencia de comandos

La validación es todo lo que ocurre antes de que se hace clic en el botón Aceptar de una herramienta. Al crear sus propias herramientas personalizadas, la validación le permite personalizar cómo responden e interactúan los parámetros con los valores y entre sí. La validación se realiza con un bloque de código de Python que se utiliza para controlar el comportamiento de la herramienta.

Para obtener más información acerca de la validación, consulte Entender la validación en las herramientas de secuencia de comandos

Puede proporcionar un comportamiento propio para el cuadro de diálogo de la herramienta de secuencia de comandos, como habilitar y deshabilitar parámetros, proporcionar valores predeterminados y actualizar palabras clave de cadena de texto. Para agregar un comportamiento propio para la herramienta de secuencia de comandos, haga clic derecho en la herramienta de secuencia de comandos, haga clic en Propiedades, y a continuación haga clic en la pestaña Validación. En el panel Validación, puede proporcionar un código Python que implementa una clase de Python denominada ToolValidator.

Aunque la clase ToolValidator se implementa mediante código Python, aún puede utilizar cualquier idioma de secuencia de comandos para realizar el trabajo actual de la herramienta.

ToolValidator es una clase Python que contiene tres métodos: initializeParameters(self), updateParameters(self) y updateMessages(self). También incluye el método estándar de inicio de clase de Python, __init__(self). Para ver y editar la clase ToolValidator, haga clic derecho en la herramienta de secuencia de comandos, haga clic en Propiedades y a continuación haga clic en la pestaña Validación. La ilustración a continuación muestra la pestaña Validación con el código de clase ToolValidator predeterminado. Haga clic en el botón Editar para editar el código y, después de editarlo, haga clic en Aceptar o Aplicar para aplicar las modificaciones.

Panel de validación

Método

Descripción

__init__

Inicia la clase ToolValidator. Importa todas las bibliotecas que necesita e inicia el objeto (self).

initializeParameters

Se invoca una vez cuando el cuadro de diálogo de la herramienta se abre por primera vez o cuando la herramienta se utiliza por primera vez en la línea de comandos.

updateParameters

Se invoca cada vez que el usuario modifica un parámetro en el cuadro de diálogo de la herramienta. Después de volver de updateParameters, el geoprocesamiento invoca su rutina de validación interna.

updateMessages

Se invoca después de volver de la rutina de validación interna. Puede examinar los mensajes creados desde la validación interna y modificarlos si lo desea.

Vista general de los métodos de ToolValidator
NotaNota:

No invoque otras herramientas de geoprocesamiento ni abra datasets en ToolValidator porque la clase ToolValidator se ejecuta cada vez que un usuario modifica algo en el cuadro de diálogo de la herramienta. Utilice las herramientas de geoprocesamiento en la secuencia de comandos, no en ToolValidator.

NotaNota:

Debe implementar los tres métodos, initializeParameters(self), updateParameters(self) y updateMessages(self). No deben hacer nada excepto volver pero se deben proporcionar para que ToolValidator sea una clase de Python válida.

A continuación se presentan algunos ejemplos del código de ToolValidator. Para obtener una descripción completa de todos los métodos y más ejemplos, consulte Programar una clase ToolValidator.

Habilitar o deshabilitar un parámetro

Este ejemplo es de la herramienta Análisis de punto caliente:

def updateParameters(self):    # If the option to use a weights file is selected (the user chose   #  "Get Spatial Weights From File"), enable the parameter for specifying    #  the file, otherwise disable it   #   if self.params[3].value == "Get Spatial Weights From File":     self.params[8].enabled = 1   else:     self.params[8].enabled = 0

Nota de codificación: Cuando configura variables booleanas, comoHabilitado, puede usar estas sintaxis:

self.params[8].enabled = 1 self.params[8].enabled = bool(1) self.params[8].enabled = True  # Note upper case: "True", not "true"

Todo número o valor que no sea cero se considera verdadero.

Configurar un valor predeterminado

Este ejemplo es también de la herramienta Análisis de punto caliente:

def updateParameters(self):   # Set the default distance threshold to 1/100 of the larger of the width   #  or height of the extent of the input features.  Do not set if there is no    #  input dataset yet, or the user has set a specific distance (Altered is true).   #    if self.params[0].value:     if not self.params[6].altered:       extent = arcpy.Describe(self.params[0].value).extent       if extent.width > extent.height:         self.params[6].value = extent.width / 100       else:         self.params[6].value = extent.height / 100    return

Actualizar un filtro

A continuación se presenta un ejemplo de la actualización dinámica de un filtro de lista de valores que incluye una lista de elección de palabras clave. Si el usuario introduce "OLD_FORMAT" en el segundo parámetro, el tercer parámetro contiene "POINT", "LINE" y "POLYGON". Si se introduce "NEW_FORMAT", el tercer parámetro contiene tres elecciones adicionales.

class ToolValidator:   def __init__(self):      import arcpy      self.params = arcpy.GetParameterInfo()    def initializeParameters(self):     return    def updateParameters(self):     # Provide default values for "file format type" and      #  "feature type in file"     #     if not self.params[1].altered:       self.params[1].value = "OLD_FORMAT"     if not self.params[2].altered:       self.params[2].value = "POINT"      # Update the value list filter of the "feature type in file" parameter      #   depending on the type of file (old vs. new format) input     #     if self.params[1].value == "OLD_FORMAT":       self.params[2].filter.list = ["POINT", "LINE", "POLYGON"]     elif self.params[1].value == "NEW_FORMAT":       self.params[2].filter.list = ["POINT", "LINE", "POLYGON",                                     "POINT_WITH_ANNO",                                     "LINE_WITH_ANNO",                                     "POLYGON_WITH_ANNO"]      return    def updateMessages(self):     return

Aquí hay otro ejemplo donde el filtro de la lista de valores en el segundo parámetro cambia según el tipo de forma encontrado en el primer parámetro, una clase de entidad:

def updateParameters(self):     # Update the value list filter in the second parameter based on the      #   shape type in the first parameter     #     stringFilter = self.params[1].filter     fc = self.params[0].value     if fc:         shapetype = arcpy.Describe(fc).shapeType.lower()         if shapetype == "point" or shapetype == "multipoint":             stringFilter.list = ["RED", "GREEN", "BLUE"]         elif shapetype == "polygon":             stringFilter.list = ["WHITE", "GRAY", "BLACK"]         else:             stringFilter.list = ["ORANGE", "INDIGO", "VIOLET"]     else:         stringFilter.list = ["RED", "GREEN", "BLUE"]      # If the user hasn't changed the keyword value, set it to the default value     #  (first value in the value list filter).     #     if not self.params[1].altered:         self.params[1].value = stringFilter.list[0]              return

Personalizar un mensaje

def updateMessages(self):   self.params[6].clearMessage()    # Check to see if the threshold distance contains a value of zero and the user has   #  specified a fixed distance band.   #   if self.params[6].value <= 0:     if self.params[3].value == "Fixed Distance Band":       self.params[6].setErrorMessage("Zero or a negative distance is invalid \                                       when using a fixed distance band. Please \                                       use a positive value greater than zero." )     elif self.params[6].value < 0:       self.params[6].setErrorMessage("A positive distance value is required \                                       when using a fixed distance band. \                                       Please specify a distance.")    return

Actualizar la descripción de los datos de salida por medio del objeto Esquema

Además de personalizar la conducta del cuadro de diálogo de la herramienta, puede utilizar ToolValidator para actualizar las descripciones de las variables de los datos de salida para ModelBuilder. Puede pensar a las variables de datos en ModelBuilder como nada más que descripciones breves de datasets, como se ilustra a continuación. Las variables de datos contienen cada propiedad a la que accede con la función Describe en Python.

Descripción básica de datos

Todas las herramientas deben actualizar la descripción de los datos de salida para su uso en ModelBuilder. Al actualizar la descripción, los procesos subsiguientes en ModelBuilder pueden observar cambios pendientes en los datos antes de ejecutar cualquier proceso. Los dos ejemplos a continuación muestran cómo los procesos subsiguientes observan cambios pendientes.

El primer ejemplo, que se ilustra a continuación, muestra un modelo que contiene las herramientas Agregar campo y Calcular campo. En Agregar campo, la variable de datos de salida, Parks (2) se actualiza para incluir el campo nuevo, TrackingID. Debido a la actualización de la salida, el cuadro de diálogo de Calcular campo muestra TrackingID en la lista de nombres de campos.

Modelo con la herramienta Recortar

El segundo ejemplo (que no se muestra) es un modelo donde la salida de la herramienta Recortar se utiliza como entrada para la herramienta De polígono a ráster. Dado que la herramienta Recortar utiliza un enfoque que "recorta según un molde" para crear las entidades de entrada, la clase de entidad de salida tiene las mismas propiedades que la clase de entidad de entrada con una excepción notable: su extensión geográfica. La extensión geográfica de la clase de entidad de salida es la intersección geométrica de las extensiones de las entidades de entrada y de recorte. La herramienta De polígono a ráster utiliza la nueva extensión geográfica para determinar un tamaño de celda predeterminado.

Dentro de la clase ToolValidator, puede utilizar un objeto de Esquema para configurar reglas para construir la descripción de la salida. Por ejemplo, puede configurar las reglas de la manera siguiente:

Los parámetros de salida tienen un esquema

El objeto de Esquema se crea mediante el geoprocesamiento. Cada parámetro de salida de tipo clase de entidad, tabla, ráster o espacio de trabajo tiene un objeto de esquema. Sólo los tipos de datos de salida de clase de entidad, tabla, ráster y espacio de trabajo tienen un esquema; los otros tipos de datos no. Accede a este esquema por medio del objeto de parámetro y configura las reglas para describir la salida. Al regresar de, updateParameters, la rutina de validación interna examina las reglas que configuró y actualiza la descripción de la salida.

Configurar dependencias

Siempre que crea una regla como "copiar los campos del dataset en el parámetro 3 y a continuación agregar un campo", tiene que decirle al objeto de Esquema qué parámetro desea copiar del (parámetro 3). Esto se realiza al agregar dependencias al objeto del parámetro. Puede agregar más de una dependencia.

def initializeParameters(self):   # Set the dependencies for the output and its schema properties   #   self.params[2].parameterDependencies = [0, 1]

parameterDependencies toma una lista de Python.

El ejemplo a continuación muestra la configuración y el uso de dependencias.

Ejemplos de configuración de dependencias: Recortar y Agregar campo

Recuerde que Recortar realiza una copia de la definición de entidades de entrada, y establece la extensión como la intersección de las entidades de entrada y las entidades de recorte. A continuación se presenta un ejemplo de cómo se implementa esta regla en ToolValidator. (Debido a que Recortar es una herramienta integrada y no una secuencia de comandos, no utiliza una clase ToolValidator de Python. Las herramientas integradas realizan la validación con rutinas internas que esencialmente son las mismas que ToolValidator. Pero si utilizó una clase ToolValidator de Python, se vería de este modo).

def initializeParameters(self):   # Set the dependencies for the output and its schema properties   #   self.params[2].parameterDependencies = [0, 1]    # Feature type, geometry type, and fields all come from the first    #  dependent (parameter 0), the input features   #   self.params[2].schema.featureTypeRule = "FirstDependency"   self.params[2].schema.geometryTypeRule = "FirstDependency"   self.params[2].schema.fieldsRule = "FirstDependency"    # The extent of the output is the intersection of the input features and    #  the clip features (parameter 1)   #   self.params[2].schema.extentRule = "Intersection"    return  def updateParameters(self):   return

Agregar campo copia la definición de un parámetro de entrada y agrega el campo especificado por el usuario. El vínculo a continuación muestra cómo se implementaría Agregar campo en ToolValidator.

Vea un ejemplo del uso de AdditionalFields

Configuración de esquema en el inicio de initializeParameters frente a updateParameters

Observe que el ejemplo de Recortar que se muestra arriba modifica el objeto de Esquema en initializeParameters y que updateParameters no hace más que regresar. Agregar campo, por otra parte, debe modificar el objeto de Esquema en updateParameters porque no tiene la definición del campo a agregar hasta que el usuario brinde la información (y se invoque updateParameters).

Se pueden considerar estos dos casos como estático frente a dinámico. Recortar no necesita nada excepto los datasets encontrados en los parámetros dependientes (caso estático), mientras que Agregar campo debe examinar otros parámetros (como nombre de campo y tipo de campo) que no son parámetros dependientes (caso dinámico).

Este comportamiento estático y dinámico es evidente en la forma en que se invoca la clase ToolValidator a continuación:

  1. Cuando el cuadro de diálogo de la herramienta se abre por primera vez, se invoca initializeParameters(). Usted configura las reglas estáticas para describir la salida. No se genera ninguna descripción de salida en este momento, dado que el usuario no tiene valores especificados para ninguno de los parámetros.
  2. Una vez que el usuario interactúa con el cuadro de diálogo de la herramienta de algún modo, se invoca updateParameters.
  3. updateParameters puede modificar el objeto de esquema para justificar el comportamiento dinámico que no puede determinarse desde las dependencias del parámetro (como agregar un campo nuevo con Agregar campo).
  4. Después de regresar de updateParameters, se invocan las rutinas de validación internas y se aplican las reglas que se encuentran en el objeto de Esquema para actualizar la descripción de los datos de salida.
  5. Entonces se invoca updateMessages. Puede examinar los mensajes de advertencia y de error que la validación interna puede haber creado y modificarlos o agregar advertencias y errores.

Nombre del dataset de salida: Clonación de salida derivada frente a salida requerida

Cuando configura la propiedad Schema.Clone como verdadera, le está indicando al geoprocesamiento que realice una copia exacta (clon) de la descripción en el primer parámetro dependiente de la lista de dependencia de parámetros. Normalmente, configura Clon como verdadero en initializeParameters en lugar de updateParameters dado que solo se debe configurar una vez.

Si el ParameterType del parámetro de salida se configura como Derivado, se realiza una copia exacta. Este es el comportamiento de la herramienta Agregar campo.

Si ParameterType se configura como Requerido, también se realiza una copia exacta pero se modifica la ruta del catálogo al dataset. Dado que la mayoría de las herramientas generan datos nuevos, este comportamiento es el más común.

Más información

Programar una clase ToolValidator brinda detalles sobre los objetos de Parámetro, Esquema y Filtro, y proporciona ejemplos de código.

Todas las herramientas basadas en secuencia de comandos, como Zona de influencia en anillos múltiples, tienen un código de ToolValidator que puede se puede examinar y desde el cual puede aprender. La mayoría de las herramientas en la caja de herramientas Estadística espacial son herramientas de secuencia de comandos y tienen una implementación ToolValidator que puede examinar.

Desafortunadamente, cometerá errores en la implementación de ToolValidator, ya sea errores de sintaxis, runtime o lógica. Depurar una clase ToolValidator muestra cómo el geoprocesamiento captura e informa errores y le brinda algunas estrategias para la depuración.

Temas relacionados

9/11/2013