Developing with the interactive interpreter can be tricky. When your class changes, you need to reload the module and create new objects with the new code.
This recipe offers a simple wrapper which will make reloading a bit easier.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | class ReloadableClass(object):
def __init__(self, mod_name, cls_name, *args, **kw):
self._mod_name = mod_name
self._cls_name = cls_name
self._args = args
self._kw = kw
self._mod = __import__(mod_name)
self._cls = getattr(self._mod, self._cls_name)
self._obj = self._cls(*args, **kw)
def __getattribute__(self, attr):
try:
return object.__getattribute__(self, attr)
except AttributeError:
return getattr(self._obj, attr)
raise AttributeError
def reload(self):
reload(self._mod)
self._cls = getattr(self._mod, self._cls_name)
self._obj = self._cls(*self._args, **self._kw)
# some_mod.py
class TestClass:
def foo(self):
print 'foo'
#print 'bar'
#def baz(self):
# print 'baz'
>>> from reloadable_class import ReloadableClass
>>> c = ReloadableClass('some_mod', 'TestClass')
>>> c.foo()
foo
>>> c.baz()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "reloadable_class.py", line 34, in __getattribute__
return getattr(self._obj, attr)
AttributeError: TestClass instance has no attribute 'baz'
>>> c.reload() # after making changes to TestClass
>>> c.foo()
foo
bar
>>> c.baz()
baz
|
As written, this wrapper simply replaces the old object with a fresh new one. None of the old state is saved. Copying of state from the old object to the new one could be added.
Other solutions involve metaclasses (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/160164) or a background watcher thread (http://aspn.activestate.com/ASPN/Mail/Message/python-list/907876)