Aktualisieren importierter Module in ArcGIS Python Toolbox?


15

Wenn Sie in ArcMap eine Python-Toolbox (.pyt) verwenden, folgen Sie in der Regel einem Muster, bei dem die .pyt-Datei selbst nur ein Wrapper ist, um Eingabeargumente zu sammeln und die Tools selbst zu definieren. Der unterstützende Code wird in separaten, für Einheiten testbaren Modulen aufbewahrt.

Beispiel:

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)

Das funktioniert sehr gut, aber ich bin während der Entwicklung auf ein frustrierendes Problem gestoßen. Klicken Sie mit der rechten Maustaste auf "-> Aktualisieren" auf ".pyt" in ArcMap aktualisiert nur den Code der .pyt-Datei. Die importierten Module werden nicht aktualisiert, sodass ich ArcMap schließen und erneut öffnen muss, wenn ich dort etwas ändere. Da ich den Code unabhängig teste, muss ich das zum Glück nicht viel tun, aber es ist immer noch ein großer Aufwand. Gibt es einen Weg, dies zu umgehen? Etwas verwandt - gibt es eine Möglichkeit, die Python-Konsole vollständig zu aktualisieren (ich habe ein benutzerdefiniertes Site-Paket, das ich auch schließen / erneut öffnen muss, um Änderungen zu übernehmen)?

Ich verwende ArcMap 10.2.1.

Antworten:


14

Ich habe diese Möglichkeit gefunden, /programming/1517038/python-refresh-reload

Die einzige Einschränkung ist, dass Variablen, die dem Modul zugewiesen wurden, erneut zugewiesen werden müssen.

Aber wie Sie es oben geschrieben haben, können Sie dies tun:

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

Auf diese Weise haben Sie jedes Mal, wenn Sie das Tool ausführen, das aktualisierte Modul. Sobald die Entwicklung abgeschlossen ist, kann diese entfernt werden.


1
Sehr hilfreich und löst das einfache Beispiel, das ich gepostet habe. Wenn support_module jedoch auch andere Hilfsmodule importiert, müssen diese auch mit reload aufgerufen werden. Ich denke, dies ist das Beste, was wir bekommen werden, da es Sinn macht, wie Python Module lädt. Ich werde Ihre als Antwort markieren, wenn am nächsten Tag oder so etwas Robusteres nicht hinzukommt.
Josh Werts

Sehr hilfreich. Ich habe festgestellt, dass es ausreicht, reload()direkt nach dem Import des unterstützenden Moduls oben in der PYT-Datei der Toolbox aufzurufen. Wenn die Toolbox also mehrere Tools enthält, muss ich das Nachladen nicht in die execute()Funktionen der einzelnen Tools kopieren .
Mike Finch

Ich verstehe nicht wirklich, wie diese Antwort das Problem löst. Ich habe meine Tools in .py-Dateien gespeichert und importiere sie mit from pyfile import Toolund füge reload(tool)Retouren hinzu typeError: reload() argument must be module. Irgendwelche Ideen?
Ratnanil

2
Ich habe die Lösung gefunden! importiere zuerst die py-Datei als Modul, lade sie neu und importiere dann die Klasse innerhalb des Moduls. Siehe: stackoverflow.com/a/6946467/4139249
Ratnanil

5

Hier ist ein anderer und robusterer Weg, als ich zuvor vorgeschlagen habe.

Ich habe dieses Modul nicht selbst verwendet, aber ich denke, es würde Ihr Problem lösen:

Python Module Reloader

Diese Bibliothek implementiert einen abhängigkeitsbasierten Modul-Reloader für Python. Im Gegensatz zur integrierten reload () -Funktion lädt dieser Reloader das angeforderte Modul und alle anderen Module, die von diesem Modul abhängig sind, neu.

In dem vorherigen Beispiel sollten alle Abhängigkeiten mit einem Aufruf geladen werden:

import reloader
reloader.enable()

import supporting_module

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

Dies ist das erste Mal, dass mir dieses Modul auffällt. Wenn Sie es also in Ihren Tools implementieren, kommentieren Sie, wie gut es für Sie funktioniert.


Guter Fund! Dies funktionierte, wenn es genau so hinzugefügt wurde, wie Sie es zeigen. Ich muss nur mit der rechten Maustaste klicken -> in der Toolbox aktualisieren, wenn sich die .pyt-Datei selbst ändert. Unterstützende Module und deren Submodule werden erfolgreich neu geladen. Eine Einschränkung - ich habe gelegentlich ein paar unerklärliche Ausnahmen und einen ArcMap-Absturz erhalten (obwohl ArcMap-Abstürze wirklich nicht so ungewöhnlich sind, leider). Hinweis - Ich habe dies nur mit dem unterstützenden Modul und einem abhängigen Untermodul getestet. Kann in Zukunft über Stabilität berichten.
Josh Werts

1
Super, danke für die Rückmeldung. Ja, wenn ich mit ArcMap fahre, fühle ich mich manchmal wie ein Crashtest-Dummy.
Cndnflyr

Leider sind mir bei diesem Reloader zu viele Stabilitätsprobleme aufgefallen, sodass ich die ausgewählte Antwort auf die in reload () integrierte Originalfunktion geändert habe. Manchmal ist einfacher besser!
Josh Werts
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.