Reimporta un modulo in Python mentre è interattivo


384

So che si può fare, ma non ricordo mai come.

Come puoi reimportare un modulo in Python? Lo scenario è il seguente: importare un modulo in modo interattivo e armeggiare con esso, ma poi riscontro un errore. Correggo l'errore nel file .py e quindi voglio reimportare il modulo fisso senza uscire da Python. Come posso farlo ?



Risposte:


370

Questo dovrebbe funzionare:

reload(my.module)

Dai documenti di Python

Ricarica un modulo importato in precedenza. L'argomento deve essere un oggetto modulo, quindi deve essere stato importato correttamente in precedenza. Questo è utile se hai modificato il file sorgente del modulo usando un editor esterno e vuoi provare la nuova versione senza lasciare l'interprete Python.

Se esegui Python 3.4 e versioni successive, esegui import importlib, quindi esegui importlib.reload(nameOfModule).

Non dimenticare le avvertenze sull'uso di questo metodo:

  • Quando un modulo viene ricaricato, il suo dizionario (contenente le variabili globali del modulo) viene mantenuto. Le ridefinizioni dei nomi sovrascriveranno le vecchie definizioni, quindi questo non è generalmente un problema, ma se la nuova versione di un modulo non definisce un nome definito dalla vecchia versione, la vecchia definizione non verrà rimossa.

  • Se un modulo importa oggetti da un altro modulo usando from ... import ..., chiamare reload()l'altro modulo non ridefinisce gli oggetti importati da esso - un modo per aggirare questo è di rieseguire l' fromistruzione, un altro è invece usare importnomi qualificati ( module.*name*).

  • Se un modulo crea un'istanza di istanze di una classe, ricaricare il modulo che definisce la classe non influisce sulle definizioni dei metodi delle istanze: continuano a utilizzare la vecchia definizione di classe. Lo stesso vale per le classi derivate.


26
se carico i miei moduli usando from filename import *. Come ricaricare?
Peter Zhu,

@PeterZhu per il caso "from mod import fcn", l'oggetto del modulo non viene aggiunto allo spazio dei nomi. Quindi è necessario importare esplicitamente il modulo, in modo da poterlo ricaricare in seguito. import foo; from foo import bar; reload(foo)
Ted

Ho provato la ricarica, così come la magia di caricamento automatico, e vedo il mio cambio di codice riflesso nello stack del messaggio di errore, ma l'errore stesso sembra ancora essere fuori dal codice non aggiornato (ad esempio, la riga dell'errore è esattamente la stessa linea come prima, che ho modificato in un commento e un commento chiaramente non può causare errori). Il mio modulo è caricato come estensione Jupyter, qualcuno potrebbe sapere se questo richiede una soluzione diversa? Grazie!
yifanwu,

1
Se hai importato la tua funzione come "importa mod come nome", allora devi fare come segue: 'import importlib importlib.reload (name)'
Noe

Questo metodo potrebbe non sovrascrivere i riferimenti di altri moduli al modulo ricaricato. Vedi stackoverflow.com/a/61617169/2642356 per una soluzione a questo.
EZLearner

288

In python 3, reloadnon è più una funzione integrata.

Se stai usando python 3.4+ dovresti invece usare reloaddalla importliblibreria:

import importlib
importlib.reload(some_module)

Se stai usando Python 3.2 o 3.3 dovresti:

import imp  
imp.reload(module)  

anziché. Vedi http://docs.python.org/3.0/library/imp.html#imp.reload

Se stai usando ipython, considera sicuramente l'uso autoreloaddell'estensione:

%load_ext autoreload
%autoreload 2

Sebbene molto codice Python sia scritto in Python 2, Python 3 sta diventando un'opzione più praticabile ogni giorno. Grazie per il consiglio!
Aaron Johnson,

40
imp.reloadè deprecato da Python 3.4, utilizzare invece la importlib.reloadfunzione .
jfs,

1
@Andrew grazie! Ho usato il% autoreload, è meraviglioso, i miei oggetti già creati hanno ottenuto automaticamente l'implementazione corretta dei metodi di classe senza doverli ricreare
jeanmi

4
Sono un po 'in ritardo, ma credo che questo non funziona se quello che avete bisogno di ricarica è una funzione o classe da all'interno del modulo: se il mio importazione statment era from mymodule import myfunc, poi importlib.reload(myfunc), importlib.reload(mymodule.myfunc), importlib.reload(mymodule)tutti danno un NameError.
Puff

@Puff vedi la mia risposta qui sotto per come reimportare una funzione
jss367


6

Se vuoi importare una specifica funzione o classe da un modulo, puoi fare questo:

import importlib
import sys
importlib.reload(sys.modules['my_module'])
from my_module import my_function

0

Sebbene le risposte fornite funzionino per un modulo specifico, non ricaricano i sottomoduli, come indicato in Questa risposta :

Se un modulo importa oggetti da un altro modulo usando from ... import ..., chiamare reload()l'altro modulo non ridefinisce gli oggetti importati da esso - un modo per aggirare questo è rieseguire l'istruzione from, un altro è invece usare importnomi qualificati ( module.*name*).

Tuttavia, se si utilizza la __all__variabile per definire l'API pubblica, è possibile ricaricare automaticamente tutti i moduli disponibili al pubblico:

# Python >= 3.5
import importlib
import types


def walk_reload(module: types.ModuleType) -> None:
    if hasattr(module, "__all__"):
        for submodule_name in module.__all__:
            walk_reload(getattr(module, submodule_name))
    importlib.reload(module)


walk_reload(my_module)

Le avvertenze riportate nella risposta precedente sono comunque valide. In particolare, la modifica di un sottomodulo che non fa parte dell'API pubblica come descritto dalla __all__variabile non sarà influenzata da un ricaricamento che utilizza questa funzione. Allo stesso modo, la rimozione di un elemento di un sottomodulo non verrà riflessa da una ricarica.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.