Changing self: if self is a tree how to set to a different self

Bart Kastermans kasterma at bart-kastermanss-macbook.local
Sat Jul 12 13:18:32 CEST 2008

Terry Reedy <tjreedy at> writes:

> Bart Kastermans wrote:
>> I am playing with some trees.  In one of the procedures I wrote
>> for this I am trying to change self to a different tree.  A tree
>> here has four members (val/type/left/right).  I found that self = SS
>> does not work; I have to write self.val = SS.val and the same for
>> the other members (as shown below).  Is there a better way to do this?
>> In the below self is part of a parse tree, F is the parse tree of a
>> function f with argument x.  If a node in the parse tree is labelled
>> f, we should replace it by the parse tree for the function f, F, with
>> the remainder of the tree substituted for the input variable for the
>> function f, here x.
>>     def elimF (self):
>>         if self.val == "f":
>>             SS = F.copy ()
>>             SS.subst ('x', self.left)
>>             self.val = SS.val        # from here: set self to be SS
>>             self.type = SS.type
>>             self.left = SS.left
>>             self.right = SS.right    # completed: set self to be SS
> If you examine nodes from their parent, I believe you can do the
> substitution in one step. Something like:
> for slot,child in ( ('left',self.left), ('right',self.right) ):
>   if child is not None:
>     if child.val == 'f':
>       setattr(self, slot, F.copy().subst('x', child.left))
>     child.elimF
> where .subst returns the modified tree.

That worked very well.  The option that looks even better to me was
just to build a copy (the exceptional case of the root of the tree
that is needed bugged me a bit).  Then self does not have to be
changed at all.  Your use of setattr made me find getattr, and this
allowed for a quite smooth (I think) implementation.

    def elimF (self):
        """ do the substitution of all nodes labelled f.

        if self.val == "f":
            ret_val = F.subst ('x', self.left)
            ret_val.left = NoneOr (ret_val.left, 'elimF')
            ret_val.right = NoneOr (ret_val.right, 'elimF')
            return ret_val
            return Tree (self.val, self.type, \
                             NoneOr (self.left, 'elimF'), \
                             NoneOr (self.right, 'elimF') )

This uses the function:

def NoneOr (tree, mem_function, *arguments):
    """ if tree is not None then tree.mem_function (arguments). """
    if tree == None:
        return None
        return getattr (tree, mem_function) (*arguments)


More information about the Python-list mailing list