Puzzling OO design problem

Michael Spencer mahs at telcopartners.com
Sat Apr 9 05:31:52 EDT 2005


George Sakkis wrote:
>><boiled down version of George's exmaple>
> 
> 
> I'm not sure if it was clear to you, but my problem is the dummy
> WorldModel_v1.MovableObject class. It doesn't do anything by itself,
> but it has to be in the inheritance chain to make its descendants work
> properly.
> 
George,

since you explicit allowed metaprogramming hacks :-), how about something like 
this (not tested beyond what you see):

class WorldVersion(type):
     """WorldVersion instances are World classes
     If a World inherits from another World: Field, Movable, Player
     automatically inherit from their corresponding superclasses"""

     def __new__(self, name, bases, clsdict):
         clslist = set(["Field", "Movable", "Player"])
         baseworld = bases[0]
         if type(baseworld) is self:
             for cls in clslist:
                 base = getattr(baseworld,cls)
                 target = clsdict.setdefault(cls, base)
                 if base is target:
                     continue
                 oldbases = list(target.__bases__)
                 if base in target.__bases__:
                     continue
                 try:
                     oldbases[oldbases.index(object)] = base
                 except ValueError:
                     oldbases.append(base)
                 target = type(target.__name__, tuple(oldbases), 
dict(target.__dict__))
                 clsdict[cls] = target



         return type.__new__(self,name, bases, clsdict)

class World1(object):
     __metaclass__ = WorldVersion
     class Field(object):
         def position(self):
             print "Positioning in World1"
     class Movable(Field):
         def move(self):
             print "Moving in World1"
     class Player(Movable):
         def passBall(self):
             print "Passing in World1"

class World2(World1):
     __metaclass__ = WorldVersion
     class Field(object):
         def position(self):
             print "Positioning in World2"
     class Movable(Field): # You still need placeholder classes
                           # but they are trivial
         pass
     class Player(Movable):
         def passBall(self):
             print "Passing in World2"

class World3(World2):
     __metaclass__ = WorldVersion
     class Player(object):
         def passBall(self):
             print "Passing in World3"


  >>> p3 = World3.Player()
  >>> p3.move()
  Moving in World1
  >>> p3.position()
  Positioning in World2
  >>> p3.passBall()
  Passing in World2
  >>>

Michael




More information about the Python-list mailing list