2012-05-01 7 views
9
$ python 
>>> import myapp 
>>> reload(myapp) 
<module 'myapp' from 'myapp.pyc'> 
>>> 

ctrl + DReload in Python-Interpreter

$ python 
>>> from myapp import * 
>>> reload(myapp) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'myapp' is not defined 

Warum dies anders verhält? Wie kann ich bei Verwendung von neu laden?

+0

Der Grund, warum ich * reload() * verwende, ist, weil ich den Quellcode des Moduls ändere und es teste und der Grund, warum ich * von myapp import * verwende, ist, weil es mir das Tippen erspart. – xralf

+1

'reload' ist mit einer * Menge * Vorsicht zu verwenden. Es verhält sich in vielerlei Hinsicht unerwartet, am schlimmsten ist, dass Klassen in vielen Versionen innerhalb der VM vorhanden sind, abhängig davon, ob alte Instanzen neu geladener Klassen vorhanden sind. 'reload' wurde aus diesem Grund aus Python 3 entfernt. Oft ist es viel einfacher, ein kleines Skript einzurichten, das alle benötigten Module aufbaut und dann mit 'Importcode 'in eine Shell fällt. code.interact (lokal = einheimisch()) '.Der Python-Interpreter startet sehr schnell, was normalerweise schneller ist, als in der readline history nach 'reload' zu suchen. –

+0

@NiklasB. Danke für den Rat, aber ich kann mir das ohne ein Beispiel nicht vorstellen. Wenn es möglich ist und Sie Zeit haben, mehr darüber zu schreiben, geben Sie bitte ein Beispiel zu einer Antwort. Oder ich kann eine neue Frage basierend auf Ihrem Kommentar erstellen, wenn Sie nicht dagegen sind. – xralf

Antwort

17

Von http://docs.python.org/library/functions.html#reload:

Wenn ein Modul importiert von einem anderen Modul-Objekte unter Verwendung von ... import ..., ruft reload() für das andere Modul nicht die von ihm importierten Objekte nicht neu definieren - Eine Möglichkeit ist, die Anweisung von Anweisung erneut auszuführen, eine andere ist die Verwendung von importierten und qualifizierten Namen (Modul. Name) stattdessen.

Also, sollten Sie so etwas wie:

from myapp import * 
.... 
import myapp 
reload(myapp) 
from myapp import * 
2

Wie kann ich bei Verwendung from myapp import * neu laden?

Sie können nicht. Dies ist einer der Gründe, warum die Verwendung von from X import * eine schlechte Idee ist.

+2

Es ist keine schlechte Idee beim Debuggen. Es spart Tipparbeit. – xralf

3

Mit from myapp import *, müssen Sie nicht einen Verweis auf das Modul in einem Variablennamen haben, so können Sie nicht einen Variablennamen verwenden, beziehen zum Modul.

Natürlich verhindert nichts, dass Sie es erneut importieren, um den Verweis auf das Modul in einem Namen zu erhalten, den Sie verwenden können. Da es schon einmal eingeführt worden ist, wird es nicht tatsächlich wieder eingeführt werden:

import myapp 
reload(myapp) 

Sie auch die Referenz direkt von sys.modules erhalten.

import sys 
reload(sys.modules["myapp]") 
+0

Durch das Importieren und Neuladen des Moduls werden keine Namen neu gebunden, die mit 'from foo import *' verbunden waren. Dies kann oder viele machen das Nachladen nicht nutzlos. – geoffspear

+0

Der Grund, warum ich * reload() * verwende, ist, weil ich den Quellcode des Moduls ändere und es teste und der Grund, warum ich * von myapp import * verwende, ist, weil es mir das Tippen erspart. – xralf

1

Um Wooble Kommentar unter Verwendung „von foo import *“ bringt alles von foo in den aktuellen Namensraum zu klären. Dies kann zu Namenskollisionen führen (wobei Sie einem bereits verwendeten Namen unbeabsichtigt einen neuen Wert zuweisen) und es außerdem schwieriger machen zu erkennen, woher etwas kommt. Während einige Bibliotheken oft auf diese Weise verwendet werden, verursacht es im Allgemeinen mehr Probleme, als es wert ist.

Da es in den aktuellen Namensraum gebracht wurde, kann es nicht einfach neu geladen werden. Es ist im Allgemeinen besser, es in einem separaten Namespace zu behalten (vielleicht mit einem kürzeren Convenience-Alias ​​wie nur m). Dies ermöglicht es Ihnen, neu zu laden (was nützlich für das Testen ist, aber selten eine gute Idee außerhalb des Testens) und hilft, den Namensraum rein zu halten.