I know there are a few questions out there touching on similar issues but what I want to understand is WHY the following behavior is observed: when I use an empty dictionary {} as the default value for a property, THE SAME EMPTY DICTIONARY is set to be the default for that property for ALL the objects that I create. Which of course means that if I subsequently add to that dictionary in Object X, the dictionary will also change in Object Y. I find this annoying and I wonder why Python doesn't initialize separate empty dictionaries when I'm initializing separate objects. Here's a more concrete example:
class Insect(object):
_description={}
@property
def description(self):
return self._description
@description.setter
def description(self,value):
self._description=value
def __init__(self,description={}):
self.description=description
def createsweirdness():
x=Insect()
y=Insect()
x.description["color"]="blue"
#I originally thought that changing x should not affect y
print "y color is "+y.description["color"]
#BUT IT DOES AFFECT Y!!! if you run this you see that "y color is blue"
class InsectNoError(object):
"""The only difference between Insect and InsectNoError is that in
InsectNoError __init__(), description does NOT have a default value of {}"""
_description={}
@property
def description(self):
return self._description
@description.setter
def description(self,value):
self._description=value
def __init__(self,description):
self.description=description
def noweirdnessanymore():
x=InsectNoError({}) #have to provide {} now, since no default in __init__
y=InsectNoError({})
x.description["color"]="blue"
print "y color is "+y.description["color"]
#again I assume that changing x should not affect y, in which case calling this function
#will lead to a KeyError...and it does
I just can't understand why you would want all your instances of a class to share exactly the same underlying dictionary for some property, BY DEFAULT...why doesn't Python give each new Insect object a different empty dictionary for the "description" property? Is this behavior a deliberate design decision, or is it a bug in Python?