# Example from James Moughan, "Unification of Methods and Functions" # comp.lang.python 5/10/2004. class Collective: class base: pass def startup(self, coll, root): #wrapper class to count creations of classes self.root = root class wrapper: def __init__(self, name, c): self.mycount = 0 self.c = c self.name = name def __call__(self, *arg): tmp = self.c(*arg) self.mycount += 1 return self.c(*arg) self.wrapper = wrapper #replace every class derived from root with a wrapper #plus build a table of the self.wrap_list = [] for name, elem in coll.__dict__.items(): try: if issubclass(elem, self.root): tmp = wrapper(name, elem) self.__dict__[name] = tmp self.wrap_list.append(tmp) except: pass #when subclassing, override this #call startup with the class name #and the root of the class heirarchy def __init__(self): self.startup(Collective, self.base) #here's the stuff to do the counting #this could be much faster with marginally more work #exercise for the reader... ;) def get_counts(self, klass): counts = [ (x.c, (self.get_sub_count(x), x.name)) \ for x in self.super_classes(klass) ] counts.append( (klass.c, (self.get_sub_count(klass), klass.name)) ) counts.sort(lambda x, y: issubclass(x[0], y[0])) return [x[-1] for x in counts] def get_sub_count(self, klass): count = klass.mycount for sub in self.sub_classes(klass): count += sub.mycount return count def super_classes(self, klass): return [x for x in self.wrap_list if issubclass(klass.c, x.c) and not x.c is klass.c] def sub_classes(self, klass): return [x for x in self.wrap_list if issubclass(x.c, klass.c) and not x.c is klass.c] class animal_farm(Collective): class Animal: pass class Mammal(Animal): pass class Bovine(Mammal): pass class Cow(Bovine): pass class Feline(Mammal): pass class Cat(Feline): pass ## class Cat(Mammal): pass def __init__(self): self.startup(animal_farm, self.Animal) a_farm = animal_farm() cat = a_farm.Cat() feline = a_farm.Mammal() bovine = a_farm.Bovine() print a_farm.get_counts(a_farm.Cow) #=> # [(2, 'Animal'), (2, 'Mammal'), (1, 'Feline')]