2011-01-12 2 views
3

Ich finde eine Möglichkeit, die Methode eines Klassenobjekts zur Laufzeit neu zu laden, hier ist das Beispiel: Ich habe zuerst eine Klasse A definiert, die auf der Datei test.py liegt.Wie wird der Code einer Methode des Klassenobjekts in Python neu geladen?

class A: 
    def __init_(self): 
     pass 
    def Message(self): 
     print "1" 

dann fange ich Python-Shell in den Linux, und führen Sie den folgenden Code ein:

>>> from test import A 
>>> a = A() 
>>> a.Message() 
1 

Jetzt vi ich die test.py in der Fliege, und ändern Sie die Methode "Message":

class A: 
    def __init_(self): 
     pass 
    def Message(self): 
     print "2" 

aber wenn ich die a.Message() in dem Python Shell auszuführen, ist das Ergebnis immer die "1" und nicht "2"

Wie schreibe ich den Code, um das Objekt 'a.Message' den aktualisierten Code ausführen zu lassen.

Vielen Dank!

chu

Antwort

4

Um das Modul im interaktiven Interpreter relaod, können Sie

import test 
reload(test) 
from test import A 

verwenden, aber dies wird nicht Instanz A beeinflussen, die bereits existieren - sie wird immer noch von der alten Art A, daher mit der alten Methode. Ich denke, es ist nicht möglich, bestehende Instanzen zu ändern, noch halte ich es für eine gute Idee.

Übrigens würde ich IPython für Code-Tests empfehlen. Es erleichtert das rekursive Reload unter Verwendung der %reload Magie und (noch nützlicher) der %run Magie zu Test-Module.

+1

+1, wirklich guter Punkt über die bestehenden Instanzen nicht zu ändern. – mtrw

0

Sie haben Ihr Modul aus dem frischen Code neu zu laden, die Klasse bekommen und wieder auf die Instanz zuordnen:

import sys 
def update_class(instance): 
    cls=instance.__class__ 
    modname=cls.__module__ 
    del sys.modules[modname] 
    module=__import__(modname) 
    instance.__class__=getattr(module,cls.__name__) 

Bei der Entwicklung und den Code zu aktualisieren Sie den gleichen Trick Instanzen zu definieren, verwenden könnten, die neu geladen ihre Klasse, wann immer sie benutzt werden.

Wenn Sie den Code von A bearbeiten, um eine Methode hinzuzufügen, dann können Sie es verwenden, ohne erneut zu instanziieren a.

Eigentlich scheint del sys.modules[modname] böse Bugs zu erstellen, für die einige Symbole keine Objekte von einer Zeile zur anderen werden. (nicht verstanden warum)

1

Ich habe gerade eine Weile versucht, dieses Problem selbst zu lösen und endete mit einer etwas anderen Lösung als die anderen hier vorgeschlagen. Ich habe es in eine gist mit vielen Kommentaren, aber wie ist die SO Art und Weise gebe ich eine kurze Erklärung hier:

Anstatt einzelne Instanzen einer alten Version einer Klasse zu ändern, oder kopieren Sie sie in neue Bei den Instanzen der neuen Klasse besteht die Idee darin, die Methoden der alten Klasse (dh die Attribute der Klasse selbst, nicht die Instanzen der Klasse) als die aktualisierten Methoden der neuen Klasse zu definieren. Es sorgt auch für die Verkettung mehrerer Versionen der Klasse.