¿Actualizar módulos importados en ArcGIS Python Toolbox?

15

Cuando use una caja de herramientas de Python (.pyt) en ArcMap, normalmente seguiré un patrón en el que el archivo .pyt en sí mismo es simplemente un contenedor para recopilar argumentos de entrada y definir las propias herramientas. El código de soporte se mantiene en módulos separados que pueden probarse en unidades.

Ejemplo:

import supporting_module

class MyTool(object):

    ...

    def execute(self, parameters, messages):
        """The source code of the tool."""
        some_input = parameters[0].valueAsText
        some_output = parameters[1].valueAsText

        supporting_module.do_something(some_input, some_output)
        arcpy.SetParameter(2, some_output)

Esto funciona muy bien, pero me he encontrado con un problema frustrante durante el desarrollo. Haga clic derecho -> Actualizar en .pyt en ArcMap solo actualiza el código del archivo .pyt. No actualiza los módulos importados, por lo que tengo que cerrar y volver a abrir ArcMap cada vez que cambie algo allí. Afortunadamente, como estoy probando el código de forma independiente, no tengo que hacer esto una tonelada, pero sigue siendo una molestia importante. ¿Hay alguna forma de evitar esto? Algo relacionado: ¿hay alguna forma de actualizar completamente la consola de Python (tengo un paquete de sitio personalizado que también debo cerrar / volver a abrir ArcMap para extraer los cambios también)?

Estoy usando ArcMap 10.2.1.

Josh Werts
fuente

Respuestas:

14

Encontré esta posibilidad, /programming/1517038/python-refresh-reload

La única advertencia es que si tiene variables asignadas al módulo, deberán asignarse nuevamente.

Pero como lo has escrito arriba, puedes hacer esto:

import supporting_module
def execute()
  reload(supporting_module)
  ...

De esta manera, cada vez que ejecute la herramienta, se asegurará de tener el módulo actualizado. Una vez que se realiza el desarrollo, esto se puede sacar.

cndnflyr
fuente
1
Extremadamente útil y esto resuelve el simple ejemplo que publiqué. Sin embargo, si support_module también importa otros módulos auxiliares, entonces también deberían llamarse con reload. Creo que esto es lo mejor que obtendremos, ya que tiene sentido con la forma en que Python carga los módulos: marcaré la suya como la respuesta si algo más robusto no aparece al día siguiente más o menos.
Josh Werts
Muy útil. He descubierto que es suficiente llamar reload()inmediatamente después de importar el módulo de soporte, en la parte superior del archivo PYT de la caja de herramientas. Por lo tanto, si la caja de herramientas contiene varias herramientas, no tengo que duplicar la recarga en la execute()función de cada herramienta .
Mike Finch
Realmente no entiendo cómo esta respuesta resuelve el problema. Tengo mis herramientas almacenadas en archivos .py y las importo usando from pyfile import Tool, agregando reload(tool)devoluciones typeError: reload() argument must be module. ¿Algunas ideas?
Ratnanil
2
¡Encontré la solución! importe el archivo py como módulo primero, vuelva a cargar y luego importe la clase dentro del módulo. Ver: stackoverflow.com/a/6946467/4139249
Ratnanil
5

Aquí hay una forma diferente y más sólida de lo que sugerí antes.

No he usado este módulo yo mismo, pero creo que resolvería su problema:

Python Module Reloader

Esta biblioteca implementa un módulo de recarga basado en dependencias para Python. A diferencia de la función incorporada reload (), este cargador volverá a cargar el módulo solicitado y todos los demás módulos que dependen de ese módulo.

Dado el ejemplo anterior, esto debería cargar todas las dependencias con una llamada:

import reloader
reloader.enable()

import supporting_module

def execute()
  reloader.reload(supporting_module)
  ...

Esta es la primera vez que noto este módulo, así que si lo implementa en sus herramientas, comente qué tan bien funciona para usted.

cndnflyr
fuente
¡Buen descubrimiento! Esto funcionó si se agrega exactamente como se muestra. Solo tengo que hacer clic con el botón derecho -> actualizar en la caja de herramientas si el archivo .pyt cambia. Los módulos de soporte y sus submódulos se están volviendo a cargar correctamente. Sin embargo, una advertencia: ocasionalmente recibí un par de excepciones inexplicables y un bloqueo de ArcMap (aunque los bloqueos de ArcMap realmente no son tan anormales, desafortunadamente). Nota: solo he probado esto con el módulo de soporte y un submódulo dependiente. Puede informar sobre la estabilidad en el futuro.
Josh Werts
1
Super, gracias por informarnos. Sí, cuando conduzco ArcMap, a veces me siento como un muñeco de prueba de choque.
cndnflyr
Desafortunadamente, me he encontrado con demasiados problemas de estabilidad con este cargador, por lo que he cambiado la respuesta seleccionada a la función incorporada original reload (). ¡A veces más simple es mejor!
Josh Werts