Changing base class of a big hierarchy
Michele Simionato
mis6 at pitt.edu
Sun Aug 3 15:08:01 EDT 2003
jjl at pobox.com (John J. Lee) wrote in message news:<873cgjyo2u.fsf at pobox.com>...
> I'm trying to change a base class of a big class hierarchy. <snip>
> What's the easiest way to do that?
>
> Maybe deep-copying the module or something, then fiddling with
> __bases__?? Or a metaclass?
>
> While I'm on the subject, does anybody have code to get a list of all
> classes in a package that derive from a particular class? Or
> something I could use to do that easily?
>
>
> John
Here is a hack that does the job (notice the word 'hack').
Suppose you have a module called x.py:
#x.py module
class B(object):
a='B' # in principle this is a very large class
class C(B):
pass
You want to change the base class B (and therefore C) without touching
the original source code. You can go along the following lines:
import inspect
from types import ModuleType
def MRO(cls):
count=0; out=["MRO of %s:" % cls.__name__]
for c in cls.__mro__:
name=c.__name__
bases=','.join([b.__name__ for b in c.__bases__])
s=" %s - %s(%s)" % (count,name,bases)
if type(c) is not type: s+="[%s]" % type(c).__name__
out.append(s); count+=1
return '\n'.join(out)
def modulesub(s,r,module):
name=module.__name__
source=inspect.getsource(module).replace(s,r)
dic={name: module}; exec source in dic # exec the modified module
module2=ModuleType(name+'2') # creates an an empty module; requires 2.3
for k,v in dic.iteritems(): setattr(module2,k,v) # populates it with dic
return module2
class B(object): # redefinition of the original class B
a='NewB'
import x
Bsource=inspect.getsource(x.B)
Bnewsource=inspect.getsource(B)
x=modulesub(Bsource,Bnewsource,x) # redefine the module
print MRO(x.C)
print x.C.a # will print NewB
The MRO function is here only for convenience, it is quite useful
in large hierarchies. .__subclasses__() is useful too.
HTH,
Michele
More information about the Python-list
mailing list