[Tutor] variable inheritance

Hugo Arts hugo.yoshi at gmail.com
Mon Mar 8 16:21:49 CET 2010


On Mon, Mar 8, 2010 at 1:57 PM, spir <denis.spir at gmail.com> wrote:
> Hello,
>
> Say I have a Tree type that may be based on 2 kinds of Node-s. Both conceptually and practically, a tree itself is a node, namely the top/root one. But a tree also has some additional tree-level behaviour, which is independant of the kind of node. Say, the node type performs all the underlying tree mechanics. Thus the Tree type looks like:
>
> class Tree(_Node):
>    def __init__(self, args):
>        _Node.__init__(self)
>        ...
>    ... tree-level methods ...
>
> The issue is the actual kind of node is not only initialised through "_Node.__init__(self)": it must first feature as super class in "class Tree(Node)". (Otherwise I get an error about wrong type of self.)
> I tried to play with __new__ in Tree and Node types, but this error seems unavoidable. Maybe I did not do it right. I can indeed have __new__ return an instance of either Node type, but then for any reason it "forgets" it is also a tree (so that calling any tree method fails).
> I there a way to do this right?
>
> Workaround ideas:
> * Make the root node an attribute of tree: unsatisfying.
> * Create a common tree type and 2 specialised ones:
> class TreeN(Tree,NodeN)
>    def __init__(self, args):
>        _NodeN.__init__(self)
>        Tree.__init__(self, args)
> # ... e basta ...
>

Design-wise, there are two ways of looking at the problem:

* A tree *is* a node, containing some amount of sub-trees/nodes (they
are the same thing)
* A tree is a data structure that has one top-level node, which in
turn contains several child-nodes, which can in turn contain
child-nodes, etc. etc.

In the first case, you really shouldn't make a separate Tree type.
They are the same thing, they should have the same behavior. This also
allows great flexibility with extracting subtrees, and has quite
elegant recursive implementations.

In the second case, the Tree is something separate from it's root
Node, and so making Tree inherit from Node really doesn't make any
sense. Use containment in this case. This case is also well suited to
iterative implementations.

What you're trying to do is a kind of mixture between the two, having
the root Node as a separate type. I would try to avoid it. If you
really must, though, making a Tree class for every node type is your
best bet. Use a class factory to prevent this from getting cumbersome:

def make_treetype(nodetype):
    class Tree(nodetype):
        def __init__(self):
            nodetype.__init__(self)
        # etc etc
    return Tree

There might also be a metaclass solution, but I'm not an expert on
that. Metaclasses tend to melt my brain.

Hugo


More information about the Tutor mailing list