0

These days I don't tend to find myself surprised with Python unless I mess around with syntax corner-cases however, this one left me quite speechless. Apologies if the question title is not great.

class foo(object):

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

    def get_l(self):
        return self.l

    @staticmethod
    def make_foo(a):
        f = foo()
        f.l.append(a)
        return f

f1 = foo.make_foo(1)
f2 = foo.make_foo(2)
print(f1.l)
print(f2.l)

Does this look obvious to you? It did to me. You should see on the output:

[1]
[2]

Actually you'll see (with 3.6.2) at least:

[1, 2]
[1, 2]

However, you'll get the expected result if you do f = foo([]) in make_foo. Now, why that's the case I don't understand. Can anyone clarify why we get this unexpected result and why passing explicitly the empty list, changes what we get?

Paulo Matos
  • 1,614
  • 17
  • 23
  • 1
    Explanation and possible dup: https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument To be clear, this behavior has nothing to do with classes or constructors. You can find the same behavior using a trivial function `def bar(a=[]): a.append(1)`. – Robᵩ Oct 05 '17 at 15:43
  • @Robᵩ you're right. It's about mutable default values. Thanks. – Paulo Matos Oct 05 '17 at 15:50
  • To be clear, the same behavior occurs with mutable or immutable objects, but it only makes a difference if the object is mutable – juanpa.arrivillaga Oct 05 '17 at 16:01

0 Answers0