0

I do the following:

class Test:
    def __init__(self, a, b, c=[]):
        self.a = a
        self.b = b
        self.c = c

t1 = Test(1,2)
t2 = Test(3,4)
t1.c.append(5)
t2.c
Out: [5]

t1 == t2
Out: False

t1.c == t2.c
Out: True

Why is changing property c of instance t1 also changing the property c of instance t2? What can I do to avoid this behaviour?

Thank You for your answers

Ho Ma
  • 9
  • 1
  • 1
    Use `def __init__(self, a, b, c=None):` and then `self.c = [] if c is None else c` instead of `self.c = c`. – 9769953 Feb 19 '21 at 21:43
  • 1
    This is the expected behavior. Here's an old thread: ["Least Astonishment" and the Mutable Default Argument](https://stackoverflow.com/q/1132941) – 001 Feb 19 '21 at 21:43

2 Answers2

0

This is just a reposting of O O's comment as an answer.

The argument c=[] is defined once at compile time, so all Test objects will share the same array. You need to set it to a None value and then test if c is None and create a new array:

class Test:
    def __init__(self, a, b, c=None):  # at compile time.
        if c is None:
            c = []   # runs when the object is created.
        self.a = a
        self.b = b
        self.c = c
0

Both instances were pointing to the same list. Your keyword argument has mutable object as the default value, this is generally not recommended and you should either use immutable objects or simply a None. This issue may also happen if you use a dictionary.

Here is a fix for this particular issue:

class Test:
    def __init__(self, a, b, c=None):
        self.a = a
        self.b = b
        self.c = c or []

t1 = Test(1,2)
t2 = Test(3,4)
t1.c.append(5)
t2.c
Out: []
Ali Shannon
  • 186
  • 3