Welcome, guest | Sign In | My Account | Store | Cart

This recipe shows how to modify the class hierarchy of an instance object after it has already been instantiated.

Python, 25 lines
 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
def adopt_class(klass, obj, *args, **kwds):
    'reclass obj to inherit klass; call __init__ with *args, **kwds'
    classname = '%s_%s' % (klass.__name__, obj.__class__.__name__)
    obj.__class__ = new.classobj(classname,  (klass, obj.__class__), {})
    klass.__init__(obj, *args, **kwds)


def demo():
    class Sandwich:
        def __init__(self, ingredients):
            self.ingredients = ingredients

        def __repr__(self):
            return reduce((lambda a,b: a+' and '+b), self.ingredients)

    class WithSpam:
        def __init__(self, spam_count):
            self.spam_count = spam_count
            
        def __repr__(self):
            return Sandwich.__repr__(self) + self.spam_count * ' and spam'

    pbs = Sandwich(['peanut butter', 'jelly'])
    adopt_class(WithSpam, pbs, 2)
    print pbs
            

Sometimes this is the cleanest way out of certain class hierarchy problems that arise when you wish to avoid module interdependencies (e.g. within a layered architecture). Also useful if you want to add functionality to objects that are created by third party modules when modifying those modules is undesirable.

In the following example, the programmer has these constraints:

  1. There are several classes in objects.py, and more will be added in the future.

  2. Objects.py must not import or know about graphics.py, since the latter is not available in all configurations. Therefore, class 'G' cannot be a base class for the objects.py classes.

  3. Graphics.py should not require modification in order to support additional classes that may be added to objects.py.

#

objects.py

class A(Base): ...

class B(Base): ...

def factory(...): ... returns an instance of A or B or ...

#

graphics.py

from recipies import adopt_class

class G: ... provides graphical capabilities

def gfactory(...): obj = factory(...) adopt_class(G, obj, ...) return obj

Created by Ken Seehof on Tue, 16 Oct 2001 (PSF)
Python recipes (4591)
Ken Seehof's recipes (3)

Required Modules

  • (none specified)

Other Information and Tasks