Welcome, guest | Sign In | My Account | Store | Cart
'Demonstrate effective use of super()'

import collections
import logging

logging.basicConfig(level='INFO')

class LoggingDict(dict):
    # Simple example of extending a builtin class
    def __setitem__(self, key, value):
        logging.info('Setting %r to %r' % (key, value))
        return super(LoggingDict, self).__setitem__(key, value)

class LoggingOD(LoggingDict, collections.OrderedDict):
    # Build new functionality by reordering the MRO
    pass

ld = LoggingDict([('red', 1), ('green', 2), ('blue', 3)])
print ld
ld['red'] = 10

ld = LoggingOD([('red', 1), ('green', 2), ('blue', 3)])
print ld
ld['red'] = 10

print '-' * 20

# ------- Show the order that the methods are called -------

def show_call_order(cls, methname):
    'Utility to show the call chain'
    classes = [cls for cls in cls.__mro__ if methname in cls.__dict__]
    print '  ==>  '.join('%s.%s' % (cls.__name__, methname) for cls in classes)

show_call_order(LoggingOD, '__setitem__')
show_call_order(LoggingOD, '__iter__')

# ------- Getting the argument signatures to match ----------

class Shape(object):
    def __init__(self, **kwds):
        self.shapename = kwds.pop('shapename')
        super(Shape, self).__init__(**kwds)

class ColoredShape(Shape):
    def __init__(self, **kwds):
        self.color = kwds.pop('color')
        super(ColoredShape, self).__init__(**kwds)

cs = ColoredShape(color='red', shapename='circle')

# -------- Making sure a root exists --------------------------

class Root(object):
    def draw(self):
        pass             # the delegation chain stops here

class Shape(Root):
    def __init__(self, **kwds):
        self.shapename = kwds.pop('shapename')
        super(Shape, self).__init__(**kwds)
    def draw(self):
        print 'Drawing.  Setting shape to:', self.shapename
        super(Shape, self).draw()

class ColoredShape(Shape):
    def __init__(self, **kwds):
        self.color = kwds.pop('color')
        super(ColoredShape, self).__init__(**kwds)
    def draw(self):
        print 'Drawing.  Setting color to:', self.color
        super(ColoredShape, self).draw()

ColoredShape(color='blue', shapename='square').draw()

# ------- Show how to wrap a non-cooperative class --------

class Moveable(object):
    # non-cooperative class that doesn't use super()
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def draw(self):
        print 'Drawing at position:', self.x, self.y

class MoveableWrapper(Root):
    # make a cooperative wrapper class for Moveable
    def __init__(self, **kwds):
        x = kwds.pop('x')
        y = kwds.pop('y')
        self.moveable = Moveable(x, y)
        super(MoveableWrapper, self).__init__(**kwds)
    def draw(self):
        self.moveable.draw()
        super(MoveableWrapper, self).draw()

class MovableColoredShape(ColoredShape, MoveableWrapper):
    pass

# -------- Complete example ---------------------------------

from collections import Counter, OrderedDict

class OrderedCounter(Counter, OrderedDict):
     'Counter that remembers the order elements are first encountered'

     def __repr__(self):
         return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))

     def __reduce__(self):
         return self.__class__, (OrderedDict(self),)

oc = OrderedCounter('abracadabra')
print oc

History