1

I am struggling to understand why instance C keeps data of instance B, even though I initialized the instance variable var with the default empty list. Why is the default argument "var = []" ignored?.

class A():
    def __init__(self, var=[]):
        self.var = var

B = A()
B.var.append(3)
C = A()
print(C.var)

The print retuns

[3]

Even stranger is this:

class A():
    def __init__(self, var=[2]):
        self.var = var

B = A()
B.var.append(3)
C = A()
print(C.var)

prints

[2, 3]

How can the statement self.var = var append to the list from the front?

Jaka Belec
  • 115
  • 4
  • Python lists are mutable objects. Hence, a new list is created once when the function is defined, and the same list is used in each successive call. That's why you should avoid using mutable objects as default arguments. Please read more [here](https://docs.python-guide.org/writing/gotchas/) [Second answer here](https://stackoverflow.com/questions/8056130/immutable-vs-mutable-types) also tells you more differences between mutable and immutable objects. – Gowtham Ramesh May 12 '20 at 17:38
  • 1
    Makes sence. I'll use None as default and an if statement to init the variable – Jaka Belec May 12 '20 at 19:06

1 Answers1

0

According to what's given here

A Python variable is a symbolic name that is a reference or pointer to an object. Once an object is assigned to a variable, you can refer to the object by that name. But the data itself is still contained within the object.

B = A()
B.var.append(3)

Here, A's reference is passed to B. So they point to the same data, but are just called by different names. So whatever operation you perform on B, you also perform on A.

Hence, later when you assign A to C, the same data is referenced by C.

If you don't want that to happen, use deepcopy:

class A():
    def __init__(self, var=[]):
        self.var = var
import copy
B = copy.deepcopy(A())
B.var.append(3)
C = A()
print(C.var)
  • This explanation does not make much sense to me. For example, if I want to create a list of objects I would do something like objects = [A([x]) for x in range(10)], I don't think I should deepcopy. – Jaka Belec May 12 '20 at 16:42