C'è un modo per cancellare "tutto" nella parte Python di JMP senza chiudere la sessione JMP (qualcosa di simile a Delete Symbols() in JSL o un modo per riavviare il kernel)?
Sto sviluppando un'applicazione che utilizza l'integrazione JMP Python con il mio collega e mentre apportiamo modifiche al codice Python dobbiamo chiudere costantemente JMP. Lo facciamo per "pulire" Python quando ci imbattiamo in problemi in cui il vecchio codice Python è nella memoria e le importazioni non sovrascrivono il codice già importato.
Moduli aggiornati che vengono ignorati. Molte sorprese e meraviglie - finché non te ne accorgi...
Argh!
del funziona?
import sys
print(sys.path)
del sys
print(sys.path)
Ci sono dei problemi . Nella maggior parte degli script Python, il problema non viene notato molto perché la durata di Python stessa è solitamente la stessa dello script. Inizieresti a notarlo se eseguissi Python in modo interattivo per una lunga sessione, facendo più cose all'interno della stessa sessione interattiva. Ciò è ulteriormente complicato dal fatto che alcuni dei pacchetti Python sono implementati in C/C++ (e persino Fortran) come NumPy. Python li carica come librerie condivise e non esiste un modo sicuro per scaricare la libreria condivisa da un processo in esecuzione, se non un riavvio. JMP si trova in una posizione simile con la libreria condivisa Python stessa, non può essere scaricata. Sì, del funziona per rilasciare oggetti. Tuttavia, del sys non sta facendo ciò che potresti aspettarti. Questo non sta eliminando o scaricando il "modulo" o scaricando le dll dipendenti, sta semplicemente eliminando l'oggetto "sys" che contiene i riferimenti al modulo caricato. L'altro aspetto è che sys è un modulo incorporato in Python, non è la stessa cosa di un modulo caricato. L'ulteriore eliminazione di 'sys' non cancella le modifiche eventualmente apportate, ad esempio aggiungendo un altro percorso a sys.path.
Se lo fai:
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
Quanto sopra è stato eseguito in una sessione interattiva in una finestra terminale. Solo l'uscita da Python e il riavvio hanno cancellato /usr/local/bin da sys.path. L'unico modo reale è tenere traccia di tutte le variabili utilizzate in una sessione e poi eliminarle alla fine della "sessione". Un modo potrebbe essere quello di mettere ogni variabile in un elenco o dizionario, quindi eliminare il contenitore alla fine della sessione.
Sto studiando l'uso di sub-interpreti Python che potrebbero consentire di impostare codice che non viene eseguito nell'ambiente globale, l'idea è che il sub-interprete sia indipendente e che la chiusura del sub-interprete agirebbe come una chiusura e un riavvio di Python. Al momento, non ho trovato un modo per chiudere e riavviare in modo sicuro l'interprete Python principale durante la durata di una sessione JMP.
La pratica Python corrente per ricaricare un modulo (a partire da Python 3.4) è
<SPAN class="hljs-keyword">import</SPAN> importlib
importlib.reload(modulename)
Il tentativo di ricaricare sys dà
>>> importlib.reload(sys)
Ricaricando numpy, si ottiene il seguente output...
>>> 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)
Notare l'avviso per l'utente:
UserWarning: il modulo NumPy è stato ricaricato (importato una seconda volta). In alcuni casi, questo può causare piccoli ma sottili problemi ed è sconsigliato. _bootstrap._exec(spec, module)
Anche utilizzando il metodo "ufficiale" di ricaricare un modulo si possono verificare dei problemi.
importlib.reload() funziona benissimo quando si sviluppa un modulo Python nel codice, poiché le modifiche alla sorgente di un modulo non saranno riflesse fino a un ricaricamento. Ciò forza potenzialmente una ricompilazione in .pyc del codice Python.