Complementing the Guilherme's answer , in fact, what happens is the evaluation of arguments in defining time of the method and how the objects in Python are treated as a reference, in the definition of the method an object is created that represents the default value and in each new instance (or called of the method), the parameter will point to that same instance. This explains why the return of id
is the same for different instances and becomes even clearer when parsing the __defaults__
attribute of the method.
According to documentation , the __defaults__
attribute is a tuple that contains the default values of a function or method. In this case, considering the code presented in the question:
class Foo:
def __init__(self, values = []):
self.values = values
We can check the value of __defaults__
of the initializer method:
print(Foo.__init__.__defaults__) # ([],)
The first value of this tuple is a changeable object that represents the default value of the values
argument, since the class definition, since in Python the class itself is an object - and the method is also an object .
Checking the return of id
of this object confirms that it represents the same reference of a.values
and b.values
:
print(id(Foo.__init__.__defaults__[0])) # 47568867296648
To confirm all that has been said in practice, just check the value in __defaults__
after an instance of Foo
that has its modified class attribute:
print(Foo.__init__.__defaults__) # ([],)
a = Foo()
a.values.append(1)
print(Foo.__init__.__defaults__) # ([1],)
That is, when creating an instance and modifying its instance attribute, this attribute being of the type changeable, the object itself, which represents the default value of the argument, stored in __defaults__
, is modified in the same way. p>
See working at Ideone .
A similar question was asked in Stack Overflow:
Why are default arguments evaluated at definition time in Python