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