Existe-t-il un moyen d'effacer « tout » du côté Python de JMP sans fermer la session JMP (quelque chose de similaire à Delete Symbols() dans JSL ou un moyen de redémarrer le noyau) ?
Je développe une application utilisant l'intégration JMP Python avec mon collègue et lorsque nous apportons des modifications au code Python, nous devons constamment fermer JMP. Nous faisons cela pour « nettoyer » le Python lorsque nous rencontrons des problèmes où l'ancien code Python est en mémoire et les importations n'écraseront pas le code déjà importé.
Modules mis à jour qui sont ignorés. Beaucoup de surprises et de merveilles - jusqu'à ce que vous vous en rendiez compte...
Argh!
est-ce que del fonctionne ?
import sys
print(sys.path)
del sys
print(sys.path)
Il y a des problèmes . Dans la plupart des scripts Python, le problème n'est pas beaucoup remarqué car la durée de vie de Python lui-même est généralement la même que le script. Vous commenceriez à le remarquer si vous exécutiez Python de manière interactive pendant une longue session, en faisant plusieurs choses dans la même session interactive. Cela est encore compliqué par le fait que certains des packages Python sont implémentés en C/C++ (et même Fortran) comme NumPy. Python les charge en tant que bibliothèques partagées, et il n'existe aucun moyen sûr de décharger la bibliothèque partagée d'un processus en cours d'exécution, autre qu'un redémarrage. JMP est dans une position similaire avec la bibliothèque partagée Python elle-même, elle ne peut pas être déchargée. Oui, del fonctionne pour libérer des objets. Cependant, del sys ne fait pas ce que vous pourriez attendre. Il ne s'agit pas de supprimer ou de décharger le « module » ou de décharger les dll dépendantes, il s'agit simplement de supprimer l'objet « sys » qui contient les références au module chargé. L'autre aspect est que sys est un module intégré à Python, pas le même qu'un module chargé. La suppression supplémentaire de « sys » ne nettoie pas les modifications que vous avez pu apporter, par exemple l'ajout d'un autre chemin à sys.path.
Si vous le faites :
sys.path.append('/usr/local/bin')
print(sys.path)
del sys
print(sys.path). # gives error on sys
import sys
print(sys.path). # still contains the /usr/local/bin addition
L'exemple ci-dessus a été exécuté dans une session interactive dans une fenêtre de terminal. Seul le fait de quitter Python et de redémarrer a effacé le fichier /usr/local/bin de sys.path. Le seul moyen réel consiste à garder une trace de toutes les variables utilisées dans une session, puis à les supprimer à la fin de la « session ». Une solution consiste à placer chaque variable dans une liste ou un dictionnaire, puis à supprimer le conteneur à la fin de la session.
Je fais des recherches sur l'utilisation de sous-interpréteurs Python qui pourraient permettre de configurer du code qui ne s'exécute pas dans l'environnement global, l'idée étant que le sous-interpréteur est indépendant et que l'arrêt du sous-interpréteur agirait comme un arrêt et un redémarrage de Python. À l'heure actuelle, je n'ai pas trouvé de moyen d'arrêter et de redémarrer en toute sécurité l'interpréteur Python principal pendant la durée de vie d'une session JMP.
La pratique Python actuelle pour recharger un module (à partir de Python 3.4) est
<SPAN class="hljs-keyword">import</SPAN> importlib
importlib.reload(modulename)
Essayer de recharger le système donne
>>> importlib.reload(sys)
Le rechargement de numpy donne le résultat suivant...
>>> importlib.reload(np)
/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/importlib/__init__.py:169: UserWarning: The NumPy module was reloaded (imported a second time). This can in some cases result in small but subtle issues and is discouraged.
_bootstrap._exec(spec, module)
Notez l'avertissement utilisateur :
Avertissement utilisateur : le module NumPy a été rechargé (importé une deuxième fois). Dans certains cas, cela peut entraîner des problèmes mineurs mais subtils et est déconseillé. _bootstrap._exec(spec, module)
Même avec la méthode « officielle », recharger un module peut entraîner des problèmes.
importlib.reload() fonctionne parfaitement lorsque vous développez un module Python dans le code, car les modifications apportées à la source d'un module ne seront pas reflétées avant un rechargement. Ce qui force potentiellement une recompilation vers .pyc du code Python.