0

I understand why the following happens in python, but it seems kind of counter intuitive. Can anyone provide an explanation of why python should behave like this? Why on the second instantiation of the class G an empty list is not created again?

class G:

    def __init__(self, members=[]):
        self.members = members

    def append(self, x):
        self.members.append(x)


a = G()
a.append(1)
a.append(2)
print(a.members)  # prints: [1, 2]

b = G()
print(b.members)  # prints: [1, 2]    <-------- why????

Edit: As mentioned in the comment this issue has been already addressed here.

  • 3
    You can find a very good summary of the reason for this behavior [here](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument). – rhurwitz Feb 09 '21 at 04:49
  • @rhurwitz right, it is just the same issue – Amir Hajibabaei Feb 09 '21 at 04:56
  • 2
    Does this answer your question? ["Least Astonishment" and the Mutable Default Argument](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) – Sabito stands with Ukraine Feb 09 '21 at 05:14

2 Answers2

1

Default values are evaluated during definition. So only one list is created and the default value always points to it.

print(id(a.members))  
print(id(b.members))  
print(a.members is b.members)

output:

140226208543200
140226208543200
True
sarartur
  • 1,178
  • 1
  • 4
  • 13
1

This has nothing to do with a class. This would also work with any plan function.

def f(y,x=[]):
    x.append(y)
    return x

print(f(5)) #returns [5]
print(f(7)) #returns [5,7]

This is happening, because when the function compiles into memory, python creates a list with a pointer that is assigned as the default of the variable "x" in the function "f". When we perform "x.append" we are telling python to append to that default list in memory for the function. To avoid this behavior you need to avoid manipulating default values (google mutable vs immutable objects).

def f(y,x=[]):
    x = list(x) #copy the default
    x.append(y)
    return x
Bobby Ocean
  • 3,120
  • 1
  • 8
  • 15