问题
I'm find a way to reload the method of a class object at runtime,here is the example: I have define a class A firstly which lies on the file test.py.
class A:
def __init_(self):
pass
def Message(self):
print "1"
then I start Python shell in the linux, and execute the following code:
>>> from test import A
>>> a = A()
>>> a.Message()
1
Now I vi the test.py in the fly, and change the method "Message":
class A:
def __init_(self):
pass
def Message(self):
print "2"
but when I execute the a.Message() in the Python shell, the result is always the "1" and not "2"
How I write the code to make the object 'a.Message' to execute the updated code.
Thank you very much!
chu
回答1:
To relaod your module in the interactive interpreter, you can use
import test
reload(test)
from test import A
But this won't affect instance of A
which already exist -- they will still be of the old type A
, hence having the old method. I think it is not possible to change existing instances, nor do I think it is a good idea.
By the way, I would recommend using IPython for code testing. It facilitates recursive reload using the %reload
magic, and (even more useful) the %run
magic to test modules.
回答2:
You have to reload your module from the fresh code, get the class and assign it back to the instance:
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__)
While developing and updating the code you could use the same trick to define instances that reload their class anytime they are used.
import sys
class ObjDebug(object):
def __getattribute__(self,k):
ga=object.__getattribute__
sa=object.__setattr__
cls=ga(self,'__class__')
modname=cls.__module__
mod=__import__(modname)
del sys.modules[modname]
reload(mod)
sa(self,'__class__',getattr(mod,cls.__name__))
return ga(self,k)
class A(ObjDebug):
pass
a=A()
If you edit the code of A to add a method, then you can use it without instantiating again a.
Actually del sys.modules[modname]
seems to create nasty bugs for which some symbols becomes None objects from one line to the other. (not understood why)
回答3:
I've just spend a while trying to solve this issue myself and ended up with a slightly different solution to the others suggested here. I've put it in a gist with plenty of comments, but as is the SO way I'll give a brief explantion here:
Rather than modify individual instances of an old version of a class, or copy them into new instances of the new class, the idea is to set the methods of the old class (i.e. the attributes of the class itself not the instances of the class) to be the updated methods from the new class. It also takes care of chaining back over multiple versions of the class.
来源:https://stackoverflow.com/questions/4670586/how-to-reload-the-code-of-a-method-of-class-object-in-python