Can I inherit member variables?

Bruno Desthuilliers onurb at xiludom.gro
Thu Sep 21 08:48:29 EDT 2006


LorcanM wrote:
(snip)

> What I'm doing is a bit more
> abstract: I'm instantiating a 'world' (as a super class) and then
> various 'worldviews' as sub-classes. The 'worldviews' must know about
> various aspects of the 'world' from which they are instantiated to be
> able to do what they need to do 

Mmmm... I suspect that you're falling into the good'ole trap of abusing
inheritance here. The fact that Worlview instances needs to know about a
World instance is usually modeled by composition, ie WorldViews are
instanciated with a world instance and keep a reference to it:

class World(object):
   pass

class WorldView(object):
  __metaclass__ = WorldViewMeta
  def __init__(self, world, *args, **kw):
    self.world = world

world = World()
wv = WorldView(world)


If you need/want to get WorldViews from the world itself, it's not much
more difficult:

class World(object):
  def get_view(self, viewtype):
    return viewtype(self)


world = World()
wv = world.get_view(WorldView)


And if you really need/want to be able to do the same thing but with the
WorldView name instead of the class itself:

class World(object):
  _viewtypes = {}

  @classmethod
  def register_view_type(cls, viewtype):
      cls._viewtypes[viewtype.__name__] = viewtype

  def get_view(self, typename, *args, **kw):
    if isinstance(typename, basestring):
      return self._viewtypes[typename](self, *args, **kw)
    else: # assume it's the class
      return typename(self, *args, **kw)

  def dothis(self):
     return "dothis"

  def dothat(self, bar):
     return bar + bar

class WorldViewMeta(type):
  def __init__(cls, classname, bases, dic):
    World.register_view_type(cls)

class WorldView(object):
  __metaclass__ = WorldViewMeta
  def __init__(self, world, *args, **kw):
    self.world = world

class SomeWorldView(WorldView):
  def __init__(self, world, foo, parrot=False):
    WorldView.__init__(self, world)
    self.foo = foo
    self.parrot = parrot

world = World()
some_view = world.get_view("SomeWorldView", 42, parrot=True)
# or
some_view = world.get_view(SomeWorldView, 42, parrot=True)


Also, if you want to be able to use the WorldViews like it was the world
itself, you can easily delegate:

class DelegateWorldView(WorldView):
  def __init__(self, world):
    WorldView.__init__(self, world)

  # 'override' World.dothat:
  def dothat(self, bar):
     bar = bar * 3
     return self.world.dothat(bar)

  # automagically delegate other stuff:
  def __getattr__(self, name):
    return getattr(self.world, name)

HTH

-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list