6

I have a little problem that I do not understand.

I have a method:

def appendMethod(self, newInstance = someObject()):
    self.someList.append(newInstace)

I call this method without attributes:

object.appendMethod()

And actually I append the list with the same instance of someObject.

But if I change it to:

def appendMethod(self):
    newInstace = someObject()
    self.someList.append(newInstance)

I get new instance of that object every time, what's the difference?

Here's an example:

class someClass():
    myVal = 0

class otherClass1():

    someList = []

    def appendList(self):
        new = someClass()
        self.someList.append(new)

class otherClass2():

    someList = []

    def appendList(self, new = someClass()):
        self.someList.append(new)

newObject = otherClass1()
newObject.appendList()
newObject.appendList()
print newObject.someList[0] is newObject.someList[1]
>>>False

anotherObject = otherClass2()
anotherObject.appendList()
anotherObject.appendList()
print anotherObject.someList[0] is anotherObject.someList[1]
>>>True
  • this question isn't *strictly* related to the mutable default value, but is about *when* default values are created. @tomek keep in mind that every function keeps a **`tuple`** of its default values in the `__defaults__` attribute. But, what does this mean? Well, surely since `tuple`s are immutable functions *cannot* create a default value every time they are called, hence the default value is created only *once* at function *definition*. Try to change `someObject` with a function like `def func(): print("called")` and see when this function gets called. – Bakuriu Sep 05 '13 at 17:56
  • This is a good question. It certainly confused me when I came from C++-land where functions are second-class objects evaluated at function execution rather than function definition. – Shashank Sep 05 '13 at 18:07

1 Answers1

3

This is because you are assigning your default argument as a mutable object.

In python, a function is an object that gets evaluated when it is defined, So when you type def appendList(self, new = someClass()) you are defining new as a member object of the function, and it does NOT get re-evaluated at execution time.

see “Least Astonishment” in Python: The Mutable Default Argument

Community
  • 1
  • 1
Cameron Sparr
  • 3,925
  • 2
  • 22
  • 31