Want - but cannot get - a nested class to inherit from outer class

castironpi at gmail.com castironpi at gmail.com
Sat Mar 8 09:44:34 CET 2008


On Mar 7, 7:46 pm, DBak <david... at gmail.com> wrote:
> > > > >  However I can't do this, because, of course, the name Tree isn't
> > > > >  available at the time that the classes _MT and _Node are defined, so
> > > > >  _MT and _Node can't inherit from Tree.
>
> > > > Not only is the name not defined, the class doesn't even exist yet.
>
> > > Yes, but, well - it certainly isn't usable yet, but some object (that
> > > will be the class when it is finished) is being built (its __dict__ is
> > > being populated, etc.) - so there's an object pointer available inside
> > > the interpreter that could be put somewhere.  But this is pedantic -
> > > you're right, the class really isn't available until after the class
> > > statement.
>
> > There is no obvious solution-- What do you mean?  If there are any at
> > all, there is significant competition without clear winners.
>
> > dict dictA:
> >    membA= 0
> >    membB= 0
>
> > dict dictB:
> >    membC= 0
>
> Thanks for your answer.  To the extent I understand it:  There is a
> difference between the class statements I was trying to nest, with the
> inner inheriting from the outer, and your dict example.  The main
> thing is that in the class example - when the inner class is being
> built (i.e., inside its class statement's block) there is no need (as
> I understand it) for the parent class to be functional at all WHILE I
> AM DEFINING METHODS on the inner class.  Sure, if the inner class had

An interesting observation.

> But in the case I'm talking about I just want to define methods on the
> inner class, using names such that when the method is eventually
> called on an instance of the inner class the attribute lookup will
> proceed with the outer class being the inner class' parent.  Creating

There are two possibilities I'm thinking of.  In both, cases you go
back after Tree is finished executing, and inform _Node and _MT of
their parentage.  I haven't tested either.

The first is, define a metaclass that allows __mro__ (method
resolution order) to be written to.  But does the look-up get
performed on the one you define?

The second is, cache _Node and _MT during creation, and go back and
reinstantiate them.

class Tree(object):
...class _MT( metaclass= placeholder ):
......def isEmpty(self): return True
......def insert(self, X): return Tree._Node(X)
...class _Node( metaclass= placeholder ):
......def isEmpty(self): return False
......def insert(self, X): return _Node(X, self, Tree._MT())
...def __init__(): return _MT()
...def merge(self, T):
......<code for merging tree T into self>
Tree._MT.complete( Tree )
Tree._Node.complete( Tree )

And similarly,

class Tree(object):
   @placeholder
...class _MT():
......def isEmpty(self): return True
......def insert(self, X): return Tree._Node(X)
   @placeholder
...class _Node( metaclass= placeholder( Tree ) ):
......def isEmpty(self): return False
......def insert(self, X): return _Node(X, self, Tree._MT())
...def __init__(): return _MT()
...def merge(self, T):
......<code for merging tree T into self>
Tree._MT.complete( Tree )
Tree._Node.complete( Tree )

Here the last lines might read:

Tree._MT= Tree._MT.complete( Tree )
Tree._Node= Tree._Node.complete( Tree )

But maybe not.  Here's a third, actually:

class Tree( placeholder ): pass
class Tree(object, metaclass= placeholderreplace( Tree ) ):
...class _MT(Tree):
......def isEmpty(self): return True
......def insert(self, X): return Tree._Node(X)
...class _Node(Tree):
......def isEmpty(self): return False
......def insert(self, X): return _Node(X, self, Tree._MT())
...def __init__(): return _MT()
...def merge(self, T):
......<code for merging tree T into self>

If you're using Python -3.0, you might even be able to get away
without metaclasses on the first one, or decorators on the second one:

class Tree(object):
...class _MT():
......def isEmpty(self): return True
......def insert(self, X): return Tree._Node(X)
   _MT= placeholder( _MT )
...class _Node( metaclass= placeholder( Tree ) ):
......def isEmpty(self): return False
......def insert(self, X): return _Node(X, self, Tree._MT())
   _Node= placeholder( _Node )
...def __init__(): return _MT()
...def merge(self, T):
......<code for merging tree T into self>
Tree._MT.complete( Tree )
Tree._Node.complete( Tree )

And once again I'm still not sure.



More information about the Python-list mailing list