Importieren Sie ein Modul in Python erneut, während Sie interaktiv sind

383

Ich weiß, dass es möglich ist, aber ich kann mich nie erinnern, wie.

Wie können Sie ein Modul in Python erneut importieren? Das Szenario ist wie folgt: Ich importiere ein Modul interaktiv und bastele daran, aber dann tritt ein Fehler auf. Ich behebe den Fehler in der .py-Datei und möchte das feste Modul erneut importieren, ohne Python zu beenden. Wie kann ich es tun ?

Stefano Borini
quelle
1
Mögliches Duplikat von Wie entlade ich ein Python-Modul (lade es neu)?
Walter
Python-Modul erneut
importieren

Antworten:

369

Das sollte funktionieren:

reload(my.module)

Aus den Python-Dokumenten

Laden Sie ein zuvor importiertes Modul neu. Das Argument muss ein Modulobjekt sein, daher muss es zuvor erfolgreich importiert worden sein. Dies ist nützlich, wenn Sie die Modulquelldatei mit einem externen Editor bearbeitet haben und die neue Version ausprobieren möchten, ohne den Python-Interpreter zu verlassen.

Wenn Sie Python 3.4 oder höher ausführen, tun Sie import importlibdies importlib.reload(nameOfModule).

Vergessen Sie nicht die Vorbehalte bei dieser Methode:

  • Wenn ein Modul neu geladen wird, bleibt sein Wörterbuch (das die globalen Variablen des Moduls enthält) erhalten. Neudefinitionen von Namen überschreiben die alten Definitionen, sodass dies im Allgemeinen kein Problem darstellt. Wenn die neue Version eines Moduls jedoch keinen Namen definiert, der von der alten Version definiert wurde, wird die alte Definition nicht entfernt.

  • Wenn ein Modul Objekte aus einem anderen Modul importiert from ... import ..., indem es reload()das andere Modul aufruft, werden die daraus importierten Objekte nicht neu definiert. Eine Möglichkeit besteht darin, die fromAnweisung erneut auszuführen , eine andere darin, stattdessen importnames ( module.*name*) zu verwenden.

  • Wenn ein Modul Instanzen einer Klasse instanziiert, wirkt sich das erneute Laden des Moduls, das die Klasse definiert, nicht auf die Methodendefinitionen der Instanzen aus. Sie verwenden weiterhin die alte Klassendefinition. Gleiches gilt für abgeleitete Klassen.

Benjamin Wohlwend
quelle
26
wenn ich meine Module mit lade from filename import *. Wie lade ich nach?
Peter Zhu
@PeterZhu Für den Fall "from mod import fcn" wird das Modulobjekt nicht zum Namensraum hinzugefügt. Sie müssen das Modul also explizit importieren, damit Sie es später neu laden können. import foo; from foo import bar; reload(foo)
Ted
Ich habe sowohl das Neuladen als auch die Magie des automatischen Ladens versucht und sehe, dass sich meine Codeänderung im Stapel der Fehlermeldung widerspiegelt, aber der Fehler selbst scheint immer noch nicht im veralteten Code zu sein (z. B. befindet sich die Fehlerzeile genau auf derselben Zeile wie zuvor, die ich in einen Kommentar geändert habe, und ein Kommentar kann eindeutig keine Fehler verursachen). Mein Modul ist als Jupyter-Erweiterung geladen. Kann jemand wissen, ob dies eine andere Problemumgehung erfordert? Vielen Dank!
Yifanwu
1
Wenn Sie Ihre Funktion wie folgt importiert haben: "Import mod as name", müssen Sie wie folgt vorgehen: 'import importlib importlib.reload (name)'
Noe
Diese Methode überschreibt möglicherweise nicht die Verweise anderer Module auf das neu geladene Modul. Eine Lösung hierfür finden Sie unter stackoverflow.com/a/61617169/2642356 .
EZLearner
287

In Python 3 reloadist keine Funktion mehr eingebaut.

Wenn Sie Python 3.4+ verwenden, sollten Sie stattdessen Folgendes reloadaus der importlibBibliothek verwenden:

import importlib
importlib.reload(some_module)

Wenn Sie Python 3.2 oder 3.3 verwenden, sollten Sie:

import imp  
imp.reload(module)  

stattdessen. Siehe http://docs.python.org/3.0/library/imp.html#imp.reload

Wenn Sie verwenden ipython, sollten Sie auf jeden Fall die autoreloadErweiterung in Betracht ziehen :

%load_ext autoreload
%autoreload 2
Andrew
quelle
Obwohl viel Python-Code in Python 2 geschrieben ist, wird Python 3 von Tag zu Tag praktikabler. Danke für den Tipp!
Aaron Johnson
40
imp.reloadist seit Python 3.4 veraltet. Verwenden Sie stattdessen die importlib.reloadFunktion .
JFS
1
@ Andrew danke! Ich habe die% autoreload verwendet, es ist wunderbar, meine bereits erstellten Objekte haben automatisch die korrigierte Implementierung der Klassenmethoden erhalten, ohne sie neu erstellen zu müssen
jeanmi
4
Ich bin ein bisschen spät, aber ich denke , das funktioniert nicht, wenn , was Sie reload benötigen eine Funktion oder Klasse von innerhalb des Moduls ist: Wenn mein Import statment ist from mymodule import myfunc, dann importlib.reload(myfunc), importlib.reload(mymodule.myfunc), importlib.reload(mymodule)alle einen Nameerror geben.
Puff
@Puff siehe meine Antwort unten für das erneute Importieren einer Funktion
jss367
46

Tatsächlich ist das Modul in Python 3 impals DEPRECATED markiert. Nun, zumindest gilt das für 3.4.

Stattdessen sollte die reloadFunktion aus dem importlibModul verwendet werden:

https://docs.python.org/3/library/importlib.html#importlib.reload

Beachten Sie jedoch, dass diese Bibliothek einige API-Änderungen mit den letzten beiden Nebenversionen hatte.

Funky-Zukunft
quelle
6

Wenn Sie eine bestimmte Funktion oder Klasse aus einem Modul importieren möchten, gehen Sie folgendermaßen vor:

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

Obwohl die bereitgestellten Antworten für ein bestimmtes Modul funktionieren, werden Submodule nicht neu geladen, wie in Diese Antwort angegeben :

Wenn ein Modul Objekte aus einem anderen Modul importiert from ... import ..., indem es reload()das andere Modul aufruft, werden die daraus importierten Objekte nicht neu definiert. Eine Möglichkeit besteht darin, die from-Anweisung erneut auszuführen, eine andere darin, stattdessen importnames ( module.*name*) zu verwenden.

Wenn Sie jedoch die __all__Variable zum Definieren der öffentlichen API verwenden, können Sie alle öffentlich verfügbaren Module automatisch neu laden:

# 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)

Die in der vorherigen Antwort genannten Einschränkungen gelten jedoch weiterhin. Insbesondere das Ändern eines Submoduls, das nicht Teil der öffentlichen API ist, wie von der __all__Variablen beschrieben, wird durch ein erneutes Laden mit dieser Funktion nicht beeinflusst. Ebenso wird das Entfernen eines Elements eines Submoduls nicht durch ein erneutes Laden wiedergegeben.

skasch
quelle