0

Using Python 2.7, we expect the following code,

class T(object):
    def __init__(self,x = list()):
        self.x = x
        self.x.append(0)
        print self.x

a = T()
b = T()

to print

[0]

[0]

However, what actually happens is the following

[0]

[0, 0]

I am unable to spot why this happen, and how I can prevent this behaviour. It is clear, that [] in the default parameter suddenly becomes a reference to an object shared by all instances of the class... But why? And how can one prevent this?

Mossa
  • 1,656
  • 12
  • 16

1 Answers1

1

I presume that you mean to take a copy of the list rather than a reference to it:

self.x = x[:]

On top of that, you have fallen foul of the fact that there is a single instance of the default parameter. Which you then modify leading to all sorts of unexpected behaviour. The normal way to deal with that is like this:

class T(object):
    def __init__(self, x = None):
        if x is None:
            x = []
        self.x = x[:]
        self.x.append(0)
        print self.x

And if you really want a reference to the supplied argument then you can replace x[:] with x in the above.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • No, the *default argument* is mutable. Which is best solved by not having a default mutable argument in the first place. – Martijn Pieters Nov 28 '14 at 08:18
  • @MartijnPieters Yes, I spotted that when I read the code more closely. I still rather imagine that the user intends for a copy to be made – David Heffernan Nov 28 '14 at 08:23