557 Stimmen

Neuladen von Untermodule in IPython

Derzeit arbeite ich an einem Python-Projekt, das Untermodule enthält und numpy/scipy verwendet. Ipython wird als interaktive Konsole verwendet. Leider bin ich mit dem Workflow, den ich derzeit verwende, nicht sehr zufrieden, ich würde mich über einige Ratschläge freuen.

In IPython wird das Framework durch einen einfachen import-Befehl geladen. Es ist jedoch oft notwendig, Code in einem der Untermodule des Frameworks zu ändern. Zu diesem Zeitpunkt ist bereits ein Modell geladen und ich benutze IPython, um damit zu interagieren.

Das Framework enthält viele Module, die voneinander abhängen, d.h. wenn das Framework initial geladen wird, importiert und konfiguriert das Hauptmodul die Untermodule. Die Änderungen am Code werden nur ausgeführt, wenn das Modul unter Verwendung von reload(main_mod.sub_mod) neu geladen wird. Dies ist umständlich, da ich alle geänderten Module einzeln unter Verwendung des vollständigen Pfads neu laden muss. Es wäre sehr praktisch, wenn reload(main_module) auch alle Untermodule neu laden würde, jedoch ohne numpy/scipy neu zu laden.

0 Stimmen

Würden Sie sich gerne näher auf Allerdings ist es oft notwendig, den Code in einem der Untermodule des Frameworks zu ändern. näher erläutern? Warum ist es also notwendig, den Code zu ändern? Danke

32 Stimmen

@eat: Das Framework wird kontinuierlich weiterentwickelt, daher gibt es ständige Änderungen an der Code-Basis.

864voto

pv. Punkte 31345

IPython kommt mit einigem automatischen Neuladen Magic:

%load_ext autoreload
%autoreload 2

Es wird alle geänderten Module jedes Mal neu laden, bevor eine neue Zeile ausgeführt wird. Die Art und Weise, wie dies funktioniert, ist etwas anders als bei dreload. Es gibt einige Einschränkungen, tippen Sie %autoreload?, um zu sehen, was schief gehen kann.


Wenn Sie diese Einstellungen immer aktivieren möchten, ändern Sie Ihre IPython-Konfigurationsdatei ~/.ipython/profile_default/ipython_config.py[1] und fügen Sie hinzu:

c.InteractiveShellApp.extensions = ['autoreload']     
c.InteractiveShellApp.exec_lines = ['%autoreload 2']

Dank an @Kos über einen Kommentar unten.

[1] Wenn Sie die Datei ~/.ipython/profile_default/ipython_config.py nicht haben, müssen Sie zuerst ipython profile create aufrufen. Oder die Datei befindet sich möglicherweise unter $IPYTHONDIR.

72 Stimmen

Ich habe c.InteractiveShellApp.extensions = ['autoreload'] und c.InteraktiveShellApp.exec_lines = ['%autoreload 2'] in meiner ~/.ipython/profile_default/ipython_config.py.

4 Stimmen

Das könnte jedoch zu Leistungseinbußen führen, also verwenden Sie es mit Vorsicht.

3 Stimmen

Der Neustart wird nur ausgeführt, wenn Sie in der IPython-Shell die Eingabetaste drücken, und ist normalerweise nicht sichtbar.

115voto

Jérôme Pouiller Punkte 7648

Das Modul namens importlib ermöglicht den Zugriff auf den Import-Internals. Insbesondere bietet es die Funktion importlib.reload():

import importlib
importlib.reload(my_module)

Im Gegensatz zu %autoreload setzt importlib.reload() auch globale Variablen zurück, die im Modul gesetzt sind. In den meisten Fällen ist dies das, was man möchte.

importlib ist erst seit Python 3.1 verfügbar. Für ältere Versionen muss das Modul imp verwendet werden.

Ich empfehle, die Dokumentation von importlib.reload() zu lesen, um eine Liste aller Besonderheiten dieser Funktion zu erhalten (rekursives Neu Laden, Fälle, in denen Definitionen alter Objekte bestehen bleiben usw.).

19 Stimmen

Über die letzten zwei Jahre habe ich diese Frage mehrmals gegoogelt, und jedes Mal ist deine Antwort genau die perfekte, nach der ich suche. Vielen Dank.

1 Stimmen

Kann nur Module neu laden.

0 Stimmen

Dies funktioniert vorausgesetzt, dass wenn Sie ein Untermodul namens mymodule.data_class neu laden möchten, müssen Sie den folgenden Code schreiben- importlib.reload(mymodule.data_class).

42voto

RafG Punkte 1184

In IPython 0.12 (und möglicherweise früher) können Sie dies verwenden:

%load_ext autoreload
%autoreload 2

Dies entspricht im Wesentlichen der Antwort von pv., mit der Ausnahme, dass die Erweiterung umbenannt wurde und jetzt mit %load_ext geladen wird.

1 Stimmen

Für mich in Jupyter-Labor funktioniert dies und es ist kurz genug, um es in alle Notizbücher einzufügen, die es benötigen.

26voto

Dennis Golomazov Punkte 14467

Aus irgendeinem Grund funktionieren weder %autoreload noch dreload für die Situation, wenn Sie Code von einem Notebook in ein anderes importieren. Nur das einfache Python reload funktioniert:

reload(module)

Basierend auf [1].

15 Stimmen

In Python 3.4+ kannst du reload im importlib-Modul finden. Siehe diese Frage.

1 Stimmen

Diese Methode funktioniert beim Hinzufügen einer Instanzmethode anders als die %autoreload Technik. Es gibt einen offenen Fehlerbericht für die Unterstützung von %autoreload dafür.

20voto

Sven Marnach Punkte 525472

IPython bietet dreload() an, um alle Untermodule rekursiv neu zu laden. Persönlich ziehe ich es vor, den %run() Magic-Befehl zu verwenden (obwohl er, wie von John Salvatier in den Kommentaren angemerkt, kein tiefgreifendes Neu laden durchführt).

13 Stimmen

Ich denke, dass (leider) %run script.py nur das Skript neu lädt, das du aufrufst, nicht die Pakete, die es importiert. Wenn du versuchst, ein Paket zu debuggen, das du gerade baust, kann das ein Schmerz sein.

5 Stimmen

NB. dreload wurde in der neueren IPython-Version (z. B. IPython 6.0) durch deepreload ersetzt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X