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