new-style-classes mixin

J.Jacob joost_jacob at hotmail.com
Sun Aug 4 13:54:50 CEST 2002


Using the mixin technique was useful with the old-style classes when
you did not want to change any source code of a class definition but
still wanted to add functionality.
With the new-style classes I wonder if something like this is still
possible?
Now that .__class__.__bases__ is read-only I need to do something
else...
The added example program shows more about this.  Note that I suppose
you do not have the source code of the CC (C Classic - old style) or C
(new-style) classes.  Or you do just not want to change -anything-
there.  So inheritance is no option.  You can still call the mixin'd
class' BC (or B) __init__() after the mixin if you like and if B(C)
even has a __init__(), but you'd have to do that explicitly.

I used the old-style mixin technique for the swc module that turns a
<type 'instance'> into an XMLRPC server, any ideas how to do this for
new style classes without inheritance?

swc is at 
http://www.liacs.nl/~jjacob/swc/swc.zip


Example source code showing the mixin technique fails with new-style
classes:

################################################################
# A couple of classic classes
#
class AC:
    def ma(self):
        print 'ma'

class BC:
    def mb(self):
        print 'mb'

class CC(AC):
    pass
#
################################################################


################################################################
# A couple of new-style classes
#
class A(object):
    def ma(self):
        print 'ma'

class B(object):
    def mb(self):
        print 'mb'

class C(object, A):
    pass
#
################################################################


def doMixin(targetInstance, extraClass):
    """    mixin extraClass to the type of targetInstance
    targetInstance is of type <type 'instance'>
    extraClass is of type <type 'class'>
    """
    targetInstance.__class__.__bases__ = (
        targetInstance.__class__.__bases__ + (extraClass,) )


cc = CC()
doMixin(cc, BC)
print cc.__class__.__bases__
""" This results in:
(<class __main__.AC at 0x00867060>, <class __main__.BC at 0x00868AB8>)
"""

c = C()
doMixin(c, B)
print cc.__class__.__bases__
""" This results in:
Traceback (most recent call last):
  File "nsc.py", line 50, in ?
    doMixin(c, B)
  File "nsc.py", line 40, in doMixin
    targetInstance.__class__.__bases__ = (
TypeError: readonly attribute
"""



More information about the Python-list mailing list