2009-03-26 5 views
322

Ich teste oft mein Modul im Python-Interpreter, und wenn ich einen Fehler sehe, aktualisiere ich schnell die .py-Datei. Aber wie kann ich den Interpreter reflektieren lassen? So weit, habe ich den Interpreter verlassen und neu eingegeben, weil das erneute Importieren der Datei für mich nicht funktioniert.Wie importiere ich ein aktuelles Paket während des Python Interpreters?

+2

Es sieht so aus, als ob diese Frage vor der Veröffentlichung von Reimport gestellt/beantwortet wurde. Siehe meine Antwort unten für neue Informationen. – kkurian

+2

Importe in Python werden zwischengespeichert, daher erhält der zweite und nachfolgende Import normalerweise den gleichen Code, selbst wenn sich die Datei geändert hat. –

Antwort

254

Update für Python3: (von den already-answered answer zitiert, da der zuletzt/Kommentar hier eine veraltete Methode vorgeschlagen)

In Python 3 reload zum imp Modul bewegt wurde. In 3.4 wurde imp zugunsten importlib veraltet, und reload wurde zu letzterem hinzugefügt. Wenn Sie 3 oder später angeben, verweisen Sie entweder auf das entsprechende Modul, wenn Sie reload aufrufen, oder importieren Sie es.

Imbiss:

  • Python3> = 3.4: importlib.reload(packagename)
  • Python3 < 3.4: imp.reload(packagename)
  • Python2: weiter unten

Verwenden Sie die reload eingebaute Funktion:

https://docs.python.org/2/library/functions.html#reload

Wenn reload(module) ausgeführt wird:

  • Python-Module Code neu kompiliert wird und der Modul-Level-Code erneut ausgeführt, um einen neuen Satz von Objekten definiert, die Namen in der Modul gebunden sind Wörterbuch. Die init-Funktion von Erweiterungsmodulen wird nicht ein zweites Mal aufgerufen.
  • Wie bei allen anderen Objekten in Python werden die alten Objekte nur dann zurückgewonnen, wenn ihre Referenzzähler auf Null gefallen sind.
  • Die Namen im Modulnamespace werden aktualisiert, um auf neue oder geänderte Objekte zu verweisen.
  • Andere Verweise auf die alten Objekte (wie z. B. Namen außerhalb des Moduls) werden nicht auf die neuen Objekte rebound zurückgesetzt und müssen in jedem Namespace aktualisiert werden, wo dies erforderlich ist.

Beispiel:

# Make a simple function that prints "version 1" 
shell1$ echo 'def x(): print "version 1"' > mymodule.py 

# Run the module 
shell2$ python 
>>> import mymodule 
>>> mymodule.x() 
version 1 

# Change mymodule to print "version 2" (without exiting the python REPL) 
shell2$ echo 'def x(): print "version 2"' > mymodule.py 

# Back in that same python session 
>>> reload(mymodule) 
<module 'mymodule' from 'mymodule.pyc'> 
>>> mymodule.x() 
version 2 
+14

Beachten Sie, dass das erneute Laden nur die angegebenen Module neu lädt; Die Importe dieses Moduls müssen ebenfalls einzeln neu geladen werden. –

+0

Ich habe es versucht, aber es hat nicht für mich funktioniert. In meinem Fall ist es eine Klasse Datei MyClass.py Klasse MyClass: def __init __ (self): return 1 def do_some_work (Selbst-): Arbeit = 2 + 3 Druck Arbeit –

+5

Beachten Sie auch, dass alle Objekte, die beziehen sich auf alles im Modul (wie eine Instanz, deren Klasse im Modul definiert ist) wird weiterhin das alte, vor dem Reload-Vorgang verwenden. Im Allgemeinen ist der Neustart des Interpreters der sauberste Weg. – Miles

33

So weit habe ich Verlassen und Wiedereintritt in den Interpreter, weil erneut die Datei importieren wieder nicht für mich funktioniert.

Ja, sage nur import wieder gibt Ihnen die vorhandene Kopie des Moduls von sys.modules.

Sie reload(module) sagen kann sys.modules zu aktualisieren und eine neue Kopie dieses einzelnen Moduls, aber wenn alle anderen Module einen Verweis auf das Original-Modul oder ein beliebiges Objekt aus dem ursprünglichen Modul haben, werden sie ihre alten Referenzen zu halten und Sehr verwirrend Dinge werden passieren.

Wenn Sie also ein Modul a haben, das von den Modulen b und b abhängt, müssen Sie 'reload b' gefolgt von 'reload a' neu laden. Wenn Sie zwei Module haben, die voneinander abhängen, was sehr häufig ist, wenn diese Module Teil desselben Pakets sind, können Sie sie nicht beide neu laden: Wenn Sie p.a neu laden, erhalten Sie einen Verweis auf die alte p.b, und umgekehrt. Der einzige Weg, dies zu tun, ist, sie beide gleichzeitig zu löschen, indem Sie ihre Artikel aus sys.modules löschen, bevor Sie sie erneut importieren. Das ist eklig und hat einige praktische Probleme mit Moduleinträgen, die keine sind, als ein Marker für einen fehlgeschlagenen relativen Import.

Und wenn Sie ein Modul haben, das Verweise auf seine Objekte an Systemmodule weiterleitet - zum Beispiel registriert es einen Codec oder fügt einen Warnungshandler hinzu - Sie stecken fest; Sie können das Systemmodul nicht neu laden, ohne den Rest der Python-Umgebung zu verwirren.

Zusammenfassend: reload() ist für alle bis auf den einfachsten Fall, dass ein eigenständiges Modul von einem eigenständigen Skript geladen wird, sehr schwierig, richtig zu kommen; Wenn Sie, wie Sie meinen, ein "Paket" verwenden, werden Sie wahrscheinlich besser mit dem Dolmetschen fortfahren.

+0

Wenn Sie jedoch über einen Testfall und ein Testskript für wechselnde Einheiten sprechen, sollte das erneute Laden von sut gut funktionieren. In der Tat bin ich umherschweifend, wenn das Hinzufügen von "neu laden (sut Modul)" etwas sein sollte, das ich als Standard in den Komponententests einschließe. –

3

Sehen Sie hier für eine gute Erklärung dafür, wie Ihre abhängigen Module nicht neu geladen und die Auswirkungen werden, die haben:

http://pyunit.sourceforge.net/notes/reloading.html

Die Art und Weise PyUnit löste es durch zwingende __import__ abhängige Module zu verfolgen war dann um sie alle aus sys.modules zu löschen und erneut zu importieren. Sie hätten sie wahrscheinlich einfach neu laden können.

+0

Destillieren Sie das ein bisschen - für mich einfache Eingabe "reload ()" funktioniert zwischen den Tests. Die Verwendung von "del modul; import module" funktioniert nicht. –

10

Grundsätzlich reload wie in allyourcode asnwer. Aber es wird nicht den Code von bereits instanziierten Objekt oder referenzierten Funktionen zugrunde liegenden ändern. Sich von seiner Antwort:

#Make a simple function that prints "version 1" 
shell1$ echo 'def x(): print "version 1"' > mymodule.py 

# Run the module 
shell2$ python 
>>> import mymodule 
>>> mymodule.x() 
version 1 
>>> x = mymodule.x 
>>> x() 
version 1 
>>> x is mymodule.x 
True 


# Change mymodule to print "version 2" (without exiting the python REPL) 
shell2$ echo 'def x(): print "version 2"' > mymodule.py 

# Back in that same python session 
>>> reload(mymodule) 
<module 'mymodule' from 'mymodule.pyc'> 
>>> mymodule.x() 
version 2 
>>> x() 
version 1 
>>> x is mymodule.x 
False 
4

nicht sicher, ob dies alles erwartet Dinge tut, aber man kann einfach so tun:

>>> del mymodule 
>>> import mymodule 
10

Kurze Antwort:

versuchen reimport: a full featured reload for Python verwenden.

Lange Antwort:

Es ist diese Frage sieht aus wie wurde die Freisetzung von reimport vor gefragt/beantwortet, die sich als „voll funktions reload für Python“ Rechnungen:

Dieses Modul will ein voll funktionsfähiger Ersatz für Pythons Reload-Funktion sein. Es zielt darauf ab, ein Reload durchzuführen, das für Python-Plugins und Erweiterungen funktioniert, die von länger laufenden Anwendungen verwendet werden.

Reimport unterstützt derzeit Python 2.4 bis 2.6.

Aufgrund seiner Natur ist dies kein vollständig lösbares Problem.Das Ziel dieses Moduls ist es, die gängigsten Arten von Updates gut funktionieren zu lassen. Es ermöglicht auch die Unterstützung einzelner Module und Pakete. Eine detailliertere Beschreibung dessen, was passiert, finden Sie auf der Übersichtsseite.

Hinweis: Obwohl die reimport ausdrücklich Python unterstützt 2.4 bis 2.6, ich habe es auf 2.7 versucht, und es scheint gut zu funktionieren.

+1

Ausgezeichneter Fund. Scheint, für einfache Fälle im Interpreter gut zu funktionieren, wenn Sie eine kleine Codeänderung machen, und das ist alles, was ich wirklich wollte ... – djs

25

In Python 3 ändert sich das Verhalten.

>>> import my_stuff 

... etwas mit my_stuff, dann später:

>>>> import imp 
>>>> imp.reload(my_stuff) 

und Sie erhalten eine brandneue, neu geladen my_stuff.

+15

Und in Python 3.4 ist 'imp' für 'importlib' veraltet:' importlib.reload (my_stuff) '. –

186

Alle obigen Antworten zu reload() oder imp.reload() sind veraltet.

reload() ist nicht länger eine eingebaute Funktion in Python 3 und imp.reload() ist als veraltet markiert (siehe Hilfe (imp)).

Es ist besser, stattdessen importlib.reload() zu verwenden.

+0

Danke. Ich verstehe nicht, warum diese Antwort keine Abstimmungen hat. Keine der anderen Lösungen funktioniert in Python 3.4. – wsaleem

+1

Beachten Sie, dass dies ein * module * -Objekt als Argument und nicht * str * benötigt. – Blaszard

+0

Das funktioniert nicht für mich. Ich erhalte eine Nachricht in der Replik und sage, dass das Modul keine Methode hat, das zu nutzen. – fraxture

1
import sys 
del sys.modules['module_name'] 
+0

die 'imp' und 'importlib' Lösungen funktionierten nicht für mich. Das hat es getan. Meine Situation war in einem Jupiter-Notizbuch, wo ich ein Keras-Modell speichern musste, aber ich hatte vergessen, vorher ein "Pip-Installation-h5py" auszuführen. Zum Zeitpunkt des Speicherns hat es eine Ausnahme ausgelöst, 'save_model requires h5py'. Dies vorweg zu setzen und das 'save_model' zu verwenden, das von' keras.models' importiert wurde (anstelle der 'model.save (...)' Funktion funktionierte – shadi

-1

Dragonflys Antwort funktionierte für mich (Python 3.4.3).

import sys 
del sys.modules['module_name'] 

Hier ist eine geringere Lösung:

exec(open("MyClass.py").read(), globals()) 
+0

Das funktioniert nicht genau wie gewünscht, da der Namensraum auf global geändert wird. Es tut uns leid. –

16

Egal wie oft Sie ein Modul zu importieren, müssen Sie die gleiche Kopie des Moduls von sys.modules erhalten - die auf den ersten import mymodule geladen wurde

Ich antworte so spät, da jede der obigen/vorherigen Antwort ein bisschen der Antwort hat, also versuche ich, es in einer einzigen Antwort zusammenzufassen.

Mit integrierten Funktion:

Für Python 2.x - Verwenden Sie die integrierte in reload(mymodule) Funktion. Für Python 3.x - Verwenden Sie die imp.reload(mymodule).

Für Python 3.4 - In Python 3.4 imp hat sich für importlib dh importlib.reload(mymodule)

paar Einschränkungen veraltet:

  • Es ist im Allgemeinen nicht sehr nützlich eingebaut, um neu zu laden oder dynamisch geladene Module. Es wird nicht empfohlen, die Module sys, __main__, builtins und andere Schlüssel zu installieren.
  • In vielen Fällen sind Erweiterungsmodule nicht so ausgelegt, dass sie mehr als einmal initialisiert werden und beim erneuten Laden in beliebigen -Arten fehlschlagen können.Wenn ein Modul importiert von einem anderen Modul-Objekte mit from ... import ..., reload() für das andere Modul Aufruf nicht die Objekte nicht neu definieren, aus importiert werden müssen - ein Weg, um dies zu wieder führen die from Anweisung, ein anderer Verwenden Sie stattdessen import und qualifizierte Namen (module.name).
  • Wenn ein Modul Instanzen einer Klasse instanziiert, hat das erneute Laden des Moduls, das die Klasse definiert, keine Auswirkungen auf die Methodendefinitionen der Instanzen - sie verwenden weiterhin die alte Klassendefinition . Dasselbe gilt für abgeleitete Klassen.

Externe Pakete:

reimport - Reimport unterstützt derzeit Python 2.4 bis 2.7.

xreload - Dies funktioniert durch Ausführen des Moduls in einem Arbeits-Namespace und dann Patch-Klassen, Methoden und Funktionen an Ort und Stelle. Dies vermeidet die Notwendigkeit, Instanzen zu patchen ( ). Neue Objekte werden in den Ziel-Namespace kopiert.

livecoding - Durch das Neuladen von Code kann eine laufende Anwendung ihr Verhalten als Reaktion auf Änderungen in den verwendeten Python-Skripts ändern. Wenn die Bibliothek erkennt, dass ein Python-Skript geändert wurde, lädt es dieses Skript neu und ersetzt die Objekte, die es zuvor für die Verwendung mit neu geladenen Versionen verfügbar gemacht hatte. Als ein Werkzeug ermöglicht es einem Programmierer, eine Unterbrechung seines Arbeitsablaufs und einen entsprechenden Fokusverlust zu vermeiden. Es ermöglicht ihnen, in einem Flusszustand zu bleiben. Wo früher möglicherweise die Anwendung neu gestartet werden musste, um geänderten Code in Kraft zu setzen, können diese Änderungen sofort angewendet werden.

Verwandte Themen