Gibt es eine Möglichkeit, wie ich „alles“ auf der Python-Seite von JMP löschen kann, ohne die JMP-Sitzung zu schließen (etwas Ähnliches wie „Delete Symbols()“ in JSL oder eine Möglichkeit, den Kernel neu zu starten)?
Ich entwickle mit meinem Kollegen eine Anwendung, die die JMP-Python-Integration nutzt, und wenn wir Änderungen am Python-Code vornehmen, müssen wir JMP ständig schließen. Wir tun dies, um Python zu „löschen“, wenn wir auf Probleme stoßen, bei denen alter Python-Code im Speicher ist und Importe bereits importierten Code nicht überschreiben.
Aktualisierte Module, die ignoriert werden. Viele Überraschungen und Wunder – bis Sie es bemerken ...
Argh!
funktioniert del ?
import sys
print(sys.path)
del sys
print(sys.path)
Es gibt Probleme . In den meisten Python-Skripten wird das Problem kaum bemerkt, da die Lebensdauer von Python selbst normalerweise der des Skripts entspricht. Sie würden es bemerken, wenn Sie Python interaktiv über eine lange Sitzung ausführen und mehrere Dinge innerhalb derselben interaktiven Sitzung tun würden. Dies wird noch dadurch komplizierter, dass einige der Python-Pakete in C/C++ (und sogar Fortran) wie NumPy implementiert sind. Python lädt diese als gemeinsam genutzte Bibliotheken, und es gibt keine sichere Möglichkeit, die gemeinsam genutzte Bibliothek aus einem laufenden Prozess zu entladen, außer durch einen Neustart. JMP befindet sich in einer ähnlichen Position mit der gemeinsam genutzten Python-Bibliothek selbst, sie kann nicht entladen werden. Ja, del funktioniert, um Objekte freizugeben. Allerdings tut del sys nicht, was Sie vielleicht erwarten. Dies löscht oder entlädt nicht das „Modul“ oder entlädt abhängige DLLs, es löscht einfach das „sys“-Objekt, das die Verweise auf das geladene Modul enthält. Der andere Aspekt ist, dass sys ein in Python integriertes Modul ist, nicht dasselbe wie ein geladenes Modul. Durch das weitere Löschen von „sys“ werden keine Änderungen gelöscht, die Sie möglicherweise vorgenommen haben, z. B. das Anhängen eines anderen Pfads an sys.path.
Wenn Sie dies tun:
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
Das Obige wurde in einer interaktiven Sitzung in einem Terminalfenster ausgeführt. Nur das Beenden und Neustarten von Python löschte /usr/local/bin aus sys.path. Die einzige wirkliche Möglichkeit besteht darin, alle in einer Sitzung verwendeten Variablen zu verfolgen und sie dann am Ende der „Sitzung“ zu löschen. Eine Möglichkeit wäre, jede Variable in eine Liste oder ein Wörterbuch einzufügen und dann den Container am Ende der Sitzung zu löschen.
Ich untersuche die Verwendung von Python-Unterinterpretern, die das Einrichten von Code ermöglichen könnten, der nicht in der globalen Umgebung ausgeführt wird. Die Idee ist, dass der Unterinterpreter unabhängig ist und das Herunterfahren des Unterinterpreters wie ein Herunterfahren und Neustarten von Python wirken würde. Derzeit habe ich keine Möglichkeit gefunden, den Haupt-Python-Interpreter während der Lebensdauer einer JMP-Sitzung sicher herunterzufahren und neu zu starten.
Die aktuelle Python-Praxis zum Neuladen eines Moduls (ab Python 3.4) ist
<SPAN class="hljs-keyword">import</SPAN> importlib
importlib.reload(modulename)
Der Versuch, das System neu zu laden, führt zu
>>> importlib.reload(sys)
Das Neuladen von Numpy ergibt die folgende Ausgabe ...
>>> 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)
Beachten Sie die Benutzerwarnung:
UserWarning: Das NumPy-Modul wurde neu geladen (ein zweites Mal importiert). Dies kann in einigen Fällen zu kleinen, aber subtilen Problemen führen und wird nicht empfohlen. _bootstrap._exec(spec, module)
Auch beim „offiziellen“ Neuladen eines Moduls können Probleme auftreten.
importlib.reload() funktioniert hervorragend, wenn Sie ein Python-Modul im Code entwickeln, da Änderungen an der Quelle eines Moduls erst bei einem Neuladen berücksichtigt werden. Dies erzwingt möglicherweise eine Neukompilierung des Python-Codes in .pyc.