#!/usr/bin/env python from __future__ import print_function from collections import OrderedDict class coop_OrderedDict(OrderedDict): """ A cooperative version of OrderedDict """ def __setitem__(self, k, v, **kwargs): # OrderedDict calls dict.__setitem__ directly skipping over LoggingDict # fortunately we can control this with dict_setitem keyword argument # calculate OrderedDict's real parent instead of skipping right to dict.__setitem__ # though depending on the hierarchy it may actually be dict.__setitem__ m = super(OrderedDict, self).__setitem__ # dict_setitem wants an unbound method unbound_m = m.im_func return super(coop_OrderedDict, self).__setitem__(k, v, dict_setitem=unbound_m) class LoggingDict(dict): """ Dummy class loggs entries to dict. Supports cooperative inheritance through use of super """ def __setitem__(self, k, v): print() print('!!! setting %-8r to %r' % (k, v)) print() return super(LoggingDict, self).__setitem__(k, v) class OrderedLoggingDict1(LoggingDict, coop_OrderedDict): pass class OrderedLoggingDict2(coop_OrderedDict, LoggingDict): pass old1 = OrderedLoggingDict1() old2 = OrderedLoggingDict2() print('adding something to class with (coop_OrderedDict, LoggingDict)') old2['hooray'] = 'it worked' print('adding something to class with (LoggingDict, coop_OrderedDict)') old1['hooray'] = 'it worked'