Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument
consider the following python test.py module:
class Container:
def __init__(self, str_list=[]):
self.str_list = str_list
def from_strings(self, st=""):
self.str_list.append(st)
return self
o1 = Container().from_strings(st="o1")
o2 = Container().from_strings(st="o2")
o3 = Container().from_strings(st="o3")
def prnt():
print("o1's list:"+str(o1.str_list))
print("o2's list:"+str(o2.str_list))
print("o3's list:"+str(o3.str_list))
if __name__ == '__main__':
prnt()
Why is the output of python test.py:
o1's list:['o1', 'o2', 'o3']
o2's list:['o1', 'o2', 'o3']
o3's list:['o1', 'o2', 'o3']
instead of:
o1's list:['o1']
o2's list:['o2']
o3's list:['o3']
(It seems like I am missing why a field (str_list) of different instances in the same module could mix up. A pointer to the python doc explaining this concept would be highly appreciated)
You created an empty list as default value in your constructor:
This list is only created once and then shared by all instances. If you wanted a separate list for each instance, you could do something like:
Now each instance creates it’s own list.
edit:
What is going on?
You have probably used default arguments like
1, or'foo'and never had a problem.These are immutable objects which can not be manipulated. Whenever you think you do, you get a new instance in stead. The collection of immutable object types includes
int,str,tuple, among others.Now
[], alist, is a mutable object which can be manipulated. So whenever you change an attribute on it, it changes the actual object and every reference to it will reflect the changes.