Recursive class | can you modify self directly?

Dave Angel davea at
Wed Jul 10 00:30:29 CEST 2013

On 07/09/2013 06:01 PM, Russel Walker wrote:
> Sorry for the vague title. Probably best to just show you the code that explains it better.
> This is a simplified example of what I want to do:
> from random import choice
> class Expr(object):
>      """
>      Expr(expr, op, val) -> an expression object.
>      """
>      def __init__(self, expr, op='', val=''):
>          self.expr = expr # can be another instance of Expression.
>          self.op = op
>          self.val = val
>      def __str__(self):
>          return ("%s %s %s" % (self.expr, self.op, self.val)).strip()
>      def expand(self):
>          self = Expr(self, choice('+-*/'), choice('12345'))
> Then I tried messing around with Expr.__new__() and Expr.__init__() but that didn't work.
> The only way I've got it to work is by doing the expanding part outside of the object, by a method of some other class. But I want the Expr class to be responsible for itself. How can I do this and why doesn't the above work?

That line in method expand() indicates that you have a fundamental 
misunderstanding of the way that names and objects interact in Python. 
Names are bound to objects by the assignment operator, but the object 
itself is not changed.  If you want to change the object that self is 
bound to, then change it by mutating it.

You don't change an existing object by binding a name to a new object, 
whether of the same or different type.  The original object remains 
unchanged.  The fact that the name is 'self' is totally irrelevant.

a = 45
b = a
a = 12

This does NOT change b.

No idea what you really wanted, but perhaps it's something like:
       def expand(self):
            self.op = choice("+-*/")
            self.val = choice("12345")

No idea what expr is supposed to represent, so I didn't try to 
manipulate it here.


More information about the Python-list mailing list