Actualisation des modules importés dans ArcGIS Python Toolbox?

15

Lorsque j'utilise une boîte à outils python (.pyt) dans ArcMap, je suivrai généralement un modèle où le fichier .pyt lui-même est simplement un wrapper pour collecter les arguments d'entrée et définir les outils eux-mêmes. Le code pris en charge est conservé dans des modules testables unitairement séparés.

Exemple:

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)

Cela fonctionne très bien mais j'ai rencontré un problème frustrant pendant le développement. Cliquez avec le bouton droit -> Actualiser sur le .pyt dans ArcMap actualise uniquement le code du fichier .pyt. Il ne rafraîchit pas les modules importés, je dois donc fermer et rouvrir ArcMap chaque fois que je change quelque chose. Heureusement, puisque je teste le code indépendamment, je n'ai pas à le faire une tonne, mais c'est toujours un problème majeur. Y a-t-il un moyen de contourner cela? Assez lié - existe-t-il un moyen d'actualiser complètement la console Python (j'ai un package de site personnalisé dont je dois également fermer / rouvrir ArcMap pour y apporter également des modifications)?

J'utilise ArcMap 10.2.1.

Josh Werts
la source

Réponses:

14

J'ai trouvé cette possibilité, /programming/1517038/python-refresh-reload

La seule mise en garde est que si des variables sont affectées au module, elles devront être affectées à nouveau.

Mais comme vous l'avez écrit ci-dessus, vous pouvez le faire:

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

De cette façon, chaque fois que vous exécuterez l'outil, vous serez sûr d'avoir le module mis à jour. Une fois le développement terminé, cela peut être supprimé.

cndnflyr
la source
1
Extrêmement utile et cela résout l'exemple simple que j'ai publié. Cependant, si le support_module importe également d'autres modules d'assistance, ils devraient également être appelés avec rechargement. Je pense que c'est le meilleur que nous obtiendrons car cela a du sens avec la façon dont Python charge les modules - je marquerai la vôtre comme la réponse si quelque chose de plus robuste ne se présente pas le lendemain.
Josh Werts
Très utile. J'ai trouvé qu'il suffit d'appeler reload()juste après l'importation du module de support, en haut du fichier PYT de la boîte à outils. Ainsi, si la boîte à outils contient plusieurs outils, je n'ai pas à dupliquer le rechargement dans la execute()fonction de chaque outil .
Mike Finch
Je ne comprends pas vraiment comment cette réponse résout le problème. J'ai mes outils stockés dans des fichiers .py et je les importe en utilisant from pyfile import Tool, en ajoutant des reload(tool)retours typeError: reload() argument must be module. Des idées?
Ratnanil
2
J'ai trouvé la solution! importez d'abord le py-File en tant que module, rechargez puis importez la classe dans le module. Voir: stackoverflow.com/a/6946467/4139249
Ratnanil
5

Voici une manière différente et plus robuste que celle que j'ai suggérée auparavant.

Je n'ai pas utilisé ce module moi-même, mais je pense que cela résoudrait votre problème:

Rechargeur de module Python

Cette bibliothèque implémente un module de rechargement basé sur les dépendances pour Python. Contrairement à la fonction intégrée reload (), ce chargeur rechargera le module demandé et tous les autres modules qui dépendent de ce module.

Étant donné l'exemple précédent, cela devrait charger toutes les dépendances avec un seul appel:

import reloader
reloader.enable()

import supporting_module

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

C'est la première fois que je remarque ce module, donc si vous l'implémentez dans vos outils, commentez comment il fonctionne pour vous.

cndnflyr
la source
Bonne trouvaille! Cela a fonctionné s'il est ajouté exactement comme vous le montrez. Je n'ai qu'à faire un clic droit -> actualiser sur la boîte à outils si le fichier .pyt lui-même change. Les modules de support et leurs sous-modules sont en cours de rechargement. Une mise en garde cependant - j'ai eu quelques exceptions inexpliquées à l'occasion et un crash ArcMap (bien que les plantages ArcMap ne soient vraiment pas anormaux, malheureusement). Remarque - Je n'ai testé cela qu'avec le module de support et un sous-module dépendant. Peut faire rapport sur la stabilité à l'avenir.
Josh Werts
1
Super, merci d'avoir signalé. Oui, en conduisant ArcMap, je me sens parfois comme un mannequin de crash test.
cndnflyr
Malheureusement, j'ai rencontré trop de problèmes de stabilité avec ce chargeur, j'ai donc changé la réponse sélectionnée en fonction intégrée de reload (). Parfois plus simple, c'est mieux!
Josh Werts