Había publicado una pregunta la semana pasada sobre la personalización de una clase de ToolValidator y obtuve algunas muy buenas respuestas. Al trabajar con las soluciones propuestas, he creado un módulo personalizado que realiza consultas en una base de datos, y será llamado por la clase ToolValidator (para proporcionar valores para las listas desplegables) y más tarde en el script de geoprocesamiento (para obtener otros parámetros basados en elementos seleccionados en listas desplegables). Sin embargo, parece que no puedo llamar al módulo personalizado en la clase ToolValidator. He estado tratando de unirme al camino sin suerte. Cuando intento aplicar estos cambios al script, aparece un error de tiempo de ejecución: [Errno 9] Descriptor de archivo incorrecto. Si comento una línea de importación, no hay errores.
sys.path.append('my_custom_module_directory')
import my_custom_module
Muchos de ustedes se preguntarán por qué no solo implemento una herramienta personalizada con ArcObjects. La razón es que mis usuarios finales no tienen los privilegios necesarios para registrar CUALQUIER dlls en su computadora.
ACTUALIZACIÓN: Esto me estaba sucediendo en ArcGIS 10. Curiosamente, inicialmente estaba agregando a la ruta dentro de la función initialiazeParameters de la clase ToolValidator. Si anexo fuera (es decir, encima) de la clase ToolValidator, todo funciona como se esperaba.
sys.path.append('C:/Working/SomeFolder')
import somescript -------->THIS WORKS
class ToolValidator:
"""Class for validating a tool's parameter values and controlling
the behavior of the tool's dialog."""
def __init__(self):
"""Setup arcpy and the list of tool parameters."""
import arcpy
sys.path.append('C:/Working/SomeFolder')
import somescript -------> THIS DOESNT WORK
self.params = arcpy.GetParameterInfo()
ACTUALIZACIÓN 2: Creo que encontré la verdadera causa de mi problema. En los fragmentos de código de esta publicación, he estado agregando lo que parecen ser rutas reales (por ejemplo, C: / Working / SomeFolder) al sys.path. En mi clase real de ToolValidator, estaba construyendo una ruta relativa usando os.path.dirname(__file__)
+ "\ my_special_folder ...". Estaba anticipando que os.path.dirname(__file__)
devolvería la ruta de la caja de herramientas, ya que contiene la clase ToolValidator. He llegado a encontrar que este no es el caso. Por lo que puedo decir, la clase ToolValidator nunca se escribe realmente en un archivo .py, y especulo que este código se pasa al intérprete de Python en la memoria, por lo que __file__
es inútil, o se conserva algún script temporal y luego execfile ( path_to_script) se llama, nuevamente renderizando__file__
inútil. Estoy seguro de que también faltan otras razones.
Para resumir, si uso una ruta codificada, sys.append funciona en cualquier lugar, las rutas relativas no funcionan tan bien en la clase ToolValidator.
fuente
Respuestas:
La forma en que hago esto es, después de iniciar ArcGIS o ArcCatalog, primero ejecute una herramienta ficticia ("Ejecutar esto una vez") llamando a un script dummy.py. Después de hacerlo, puede importar scripts de python en el validador utilizando sys.argv [0]. Esto apuntará a la carpeta donde se ubicó el primer script. A partir de entonces, puede importar el script necesario en la clase de validación
El script dummy.py llamado por la herramienta "Ejecutar esto una vez":
Lo siento, no puedo obtener el formato correcto Saludos, Maarten Tromp
fuente
¡Finalmente resolvió este horrible error! Por ejemplo, cuando intenta aplicar cambios para importar un módulo o paquete relativo, puede ver el siguiente error:
Opción 1: solo
para el desarrollador, agregue la ruta completa al módulo a PYTHONPATH . Deberá reiniciar ArcMap / ArcCatalog antes de que surta efecto. Use el siguiente código para importar el módulo desde una ruta relativa (para la implementación). No se preocupe, el usuario final no necesita ninguna adición a su variable PYTHONPATH, ¡funcionará!
Opción 2:
agregue una línea adicional en el código a continuación para agregar la ruta codificada, por ejemplo: sys.path.append (r "c: \ temp \ test \ scripts")
Cuando esté listo para implementar, tiene un directorio extraño, pero no importa, todo debería funcionar en la computadora del usuario final porque la primera ruta que agregó fue el directorio relativo (nuestro objetivo era superar el cuadro de diálogo de falla).
Código común a ambas opciones:
Actualizar
¡Adiós mal corte y pegado! Actualicé el ejemplo de código para que la clase ToolValidator se importe desde la biblioteca. Corto y pego solo una vez cuando los parámetros de la herramienta se establecen por primera vez. Guardo este fragmento de código en la cadena de documentos del ToolValidator que se está importando.
En este ejemplo, el nombre del directorio fuente se basa en el nombre tbx. Este enfoque evita colisiones si tiene dos cajas de herramientas con diferentes directorios de origen. El estándar que utilicé para nombrar la carpeta de origen es el siguiente:
TOOLBOXNAME__anything.tbx -> TOOLBOXNAME.src
¿Por qué el "__ cualquier cosa"? Dado que los archivos binarios no pueden fusionarse en nuestro DVCS, podemos asignar herramientas a individuos y no preocuparnos por perder los cambios. Cuando se finaliza la herramienta, se corta y se pega en el maestro.
También necesitaba acceder a los archivos en la carpeta de origen para completar un menú desplegable, use este método para obtener la ruta a la caja de herramientas desde su módulo importado:
fuente
Poner las importaciones en la parte superior del módulo de validación, fuera de la
ToolValidator
clase, parece funcionar bien para mí: estoy en 10.0 SP2. Sin embargo, no estoy haciendo nada con el módulo importado en ninguna parte excepto enupdateParameters
.fuente
Pude mover mi validación a un archivo py importándola y llamándola desde la validación de la herramienta TBX existente. La clave estaba llamando a la importación dentro del constructor. Si lo llamé desde fuera de la clase ToolValidator, la importación falló. Esto es lo que tenía dentro de la pestaña de validación de TBX.
Mi lógica de validación luego vivía en ExportParcelIntersected.ToolValidator (). Donde podría mantenerse más fácil.
fuente