In Python kann ich import X
das Modul mit neu laden , nachdem ich ein Modul X in einer Interpretersitzung mit importiert habe und das Modul außen geändert hat reload(X)
. Die Änderungen werden dann in meiner Dolmetschersitzung verfügbar.
Ich frage mich, ob dies auch möglich ist, wenn ich eine Komponente Y aus Modul X mit importiere from X import Y
.
Die Anweisung reload Y
funktioniert nicht, da Y kein Modul selbst ist, sondern nur eine Komponente (in diesem Fall eine Klasse) innerhalb eines Moduls.
Ist es überhaupt möglich, einzelne Komponenten eines Moduls neu zu laden, ohne die Interpretersitzung zu verlassen (oder das gesamte Modul zu importieren)?
BEARBEITEN:
Zur Verdeutlichung geht es darum, eine Klasse oder Funktion Y aus einem Modul X zu importieren und bei einer Änderung neu zu laden, nicht ein Modul Y aus einem Paket X.
quelle
... possible ... import a component Y from module X
" vs "question is ... importing a class or function X from a module Y
". Ich füge eine Bearbeitung zu diesem Effekt hinzu.Antworten:
Wenn Y ein Modul (und X ein Paket) ist
reload(Y)
wird in Ordnung sein - sonst werden Sie sehen, warum Python gute Styleguides (wie mein Arbeitgeber) sagen nie Import nichts außer einem Modul (dieses ist von vielen großen Gründe aus - Trotzdem importieren die Leute weiterhin Funktionen und Klassen direkt, egal wie sehr ich erkläre, dass es keine gute Idee ist ;-).quelle
import this
von der interaktiven Eingabeaufforderung, um das Zen of Python zu sehen); und all die Gründe, warum Namespaces eine großartige Idee sind (unmittelbare lokale visuelle Hinweise darauf, dass der Name nachgeschlagen wird, einfache Verspottung / Injektion in Tests, Fähigkeit zum Neuladen, Fähigkeit eines Moduls, sich durch Neudefinition einiger Einträge flexibel zu ändern, vorhersehbar und kontrollierbar Verhalten bei der Serialisierung und Wiederherstellung Ihrer Daten [[z. B. durch Beizen und Entpicken]] usw. - ein SO-Kommentar ist kaum lang genug, um diesem reichen, langen Argument gerecht zu werden !!! -)importlib
Paket verschoben wurde .importlib.reload(Y)
docs.python.org/3.4/library/… siehe auch stackoverflow.com/questions/961162/…Antworten
Nach meinen Tests
reload(X)
funktioniert die markierte Antwort, die eine einfache andeutet , nicht.Nach allem, was ich sagen kann, lautet die richtige Antwort:
Prüfung
Mein Test war der folgende (Python 2.6.5 + bpython 0.9.5.2)
X.py:
bpython:
quelle
Foo
das__init__.py
ein Submodul abruft ... Ich werde eine Antwort als Gegenbeispiel posten.quelle
Zunächst einmal sollten Sie Reload überhaupt nicht verwenden, wenn Sie dies vermeiden können. Nehmen wir jedoch an, Sie haben Ihre Gründe (dh das Debuggen in IDLE).
Beim erneuten Laden der Bibliothek werden die Namen nicht wieder in den Namespace des Moduls übernommen. Weisen Sie dazu einfach die Variablen neu zu:
Sie können dies auf einige andere Arten tun. Sie könnten den Prozess automatisieren, indem Sie den lokalen Namespace durchsuchen und alles neu zuweisen, was aus dem betreffenden Modul stammt, aber ich denke, wir sind böse genug.
quelle
Wenn Sie dies tun möchten:
Tun Sie dies stattdessen:
Sie können myobject jetzt genauso verwenden, wie Sie es geplant haben (ohne die lästigen unlesbaren mymodule-Referenzen überall).
Wenn Sie interaktiv arbeiten und myobject von mymodule neu laden möchten, können Sie jetzt Folgendes verwenden:
quelle
Angenommen
from X import Y
, Sie haben verwendet , haben Sie zwei Möglichkeiten:oder
Einige Überlegungen:
A. Wenn der Importbereich nicht modulweit ist (z. B. Import in eine Funktion), müssen Sie die zweite Version verwenden.
B. Wenn Y von einem anderen Modul (Z) in X importiert wird - Sie müssen Z neu laden, dann X neu laden und dann Ihr Modul neu laden. Selbst das Neuladen aller Module (z. B. using
[ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ]
) kann X vor dem erneuten Laden von Z neu laden - und dann den Wert von Y nicht aktualisieren.quelle
reload()
ModulX
,reload()
ModulimportY
ausX
.Beachten Sie, dass durch das erneute Laden bereits erstellte Objekte, die in anderen Namespaces gebunden sind, nicht geändert werden (auch wenn Sie dem Styleguide von Alex folgen).
quelle
Wenn Sie in einer jupyter Umgebung arbeiten, und haben Sie bereits
from module import function
die magische Funktion verwenden,autoreload
durchDie Einführung
autoreload
in IPython finden Sie hier .quelle
Um den Antworten von AlexMartelli und Catskul nachzugehen , gibt es einige wirklich einfache, aber böse Fälle, die verwirrend zu sein scheinen
reload
zumindest in Python 2 .Angenommen, ich habe den folgenden Quellbaum:
mit folgendem Inhalt:
init.py:
bar.py:
Dies funktioniert einwandfrei ohne
reload
:Aber versuchen Sie neu zu laden und es hat entweder keine Wirkung oder korrumpiert Dinge:
Der einzige Weg, wie ich sicherstellen konnte, dass das
bar
Submodul neu geladen wurde, warreload(foo.bar)
: Die einzige Möglichkeit, auf die neu geladeneQuux
Klasse zuzugreifen, besteht darin, sie vom neu geladenen Untermodul zu erreichen und zu greifen. aber dasfoo
Modul selbst hielt am ursprünglichenQuux
Klassenobjekt fest, vermutlich weil es verwendetfrom bar import Bar, Quux
(anstattimport bar
gefolgt vonQuux = bar.Quux
); Außerdem war dieQuux
Klasse nicht mehr mit sich selbst synchronisiert, was nur bizarr ist.quelle