By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,091 Members | 1,546 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,091 IT Pros & Developers. It's quick & easy.

Python bug with dictionary

P: n/a
or is it just me?

I am having a problem with using a dictionary as an attribute of a
class. This happens in python 1.5.2 and 2.2.2 which I am accessing
through pythonwin builds 150 and 148 respectively

In the sample code you see that I have class Item and class Dict
class Dict contains a dictionary called items. The items dictionary
will contain instances of Item that are keyed off of the Item name. In
__main__ I create two distinct instances of Dict and 4 distinct
instances of Item. By using the accessor method addItem() in Dict I add
the instances of Item to Dict. In this case I add Item1 and Item2 to
Dict1 and I add Item3 and Item4 to Dict2. When this is done I print
out the instances of Dict and of Item. It appears that the dictionary
items in each of the Dict instances is the exact same instance even
though they were created as distinctly separate classes. The print out
of the results shows them at the same memory address. The items
dictionary inside of each Dict object have the same id when I do
id(dict1.items) and id(dict2.items). This means that each of the items
dictionary in the Dict instances has all four items in it, even though
each should only have two. Apparently when I add the first to Item
instances to dict1 and then the second two Item instances to dict2 they
are being added to the same items dictionary.

If I assign the Item instances to the items dictionary without using the
accessor method this does not occur. I have also tried a test with
lists with and without accessor method. This works fine also. The
simple solution is not to use accessor method but shouldn't this work?

Dale
class Dict:
items = {}
name = ""

def addItem(self,item,name):
self.items[name] = item
def setName(self,name):
self.name = name

def getName(self):
return self.name

def printItemKeys(self):
print "Dictonary Keys: ",self.items.keys()
class Item:
name = ""

def getName(self):
return self.name

def setName(self,name):
self.name = name
if __name__ == '__main__':

dict1 = Dict()
dict1.setName("dict1")

dict2 = Dict()
dict2.setName("dict2")

item1 = Item()
item1.setName("item1")

item2 = Item()
item2.setName("item2")

item3 = Item()
item3.setName("item3")

item4 = Item()
item4.setName("item4")

print "Item 1: ",item1
print "Item 2: ",item2
print "Item 3: ",item3
print "Item 4: ",item4

print "\n"

dict1.addItem(item1,item1.getName())
dict1.addItem(item2,item2.getName())

dict2.addItem(item3,item3.getName())
dict2.addItem(item4,item4.getName())

print "Dictionary Object: ",dict1
print "Dictionary Name: ",dict1.getName()
dict1.printItemKeys()
print "Dictionary Keys: ",dict1.items.keys()
print "Dictionary Item Objects: ",dict1.items
print "\n"
print "Dictionary Object: ",dict2
print "Dictionary Name: ",dict2.getName()
dict2.printItemKeys()
print "Dictionary Keys: ",dict2.items.keys()
print "Dictionary Item Objects: ",dict2.items
print "\n"
print "ID of items in dict1: " + str(id(dict1.items))
print "ID of itmes in dict2: " + str(id(dict2.items))

Item 1: <__main__.Item instance at 0x00778F20>
Item 2: <__main__.Item instance at 0x00779240>
Item 3: <__main__.Item instance at 0x00779518>
Item 4: <__main__.Item instance at 0x00779820>
Dictionary Object: <__main__.Dict instance at 0x00778BE8>
Dictionary Name: dict1
Dictonary Keys: ['item2', 'item3', 'item1', 'item4']
Dictionary Keys: ['item2', 'item3', 'item1', 'item4']
Dictionary Item Objects: {'item2': <__main__.Item instance at
0x00779240>, 'i
tem3': <__main__.Item instance at 0x00779518>, 'item1': <__main__.Item
instance
at 0x00778F20>, 'item4': <__main__.Item instance at 0x00779820>}
Dictionary Object: <__main__.Dict instance at 0x00778BB0>
Dictionary Name: dict2
Dictonary Keys: ['item2', 'item3', 'item1', 'item4']
Dictionary Keys: ['item2', 'item3', 'item1', 'item4']
Dictionary Item Objects: {'item2': <__main__.Item instance at
0x00779240>, 'i
tem3': <__main__.Item instance at 0x00779518>, 'item1': <__main__.Item
instance
at 0x00778F20>, 'item4': <__main__.Item instance at 0x00779820>}
ID of items in dict1: 8016928
ID of itmes in dict2: 8016928

Jul 18 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
none wrote:
or is it just me?

I am having a problem with using a dictionary as an attribute of a
class. This happens in python 1.5.2 and 2.2.2 which I am accessing
through pythonwin builds 150 and 148 respectively

In the sample code you see that I have class Item and class Dict
class Dict contains a dictionary called items. The items dictionary
will contain instances of Item that are keyed off of the Item name. In
__main__ I create two distinct instances of Dict and 4 distinct
instances of Item. By using the accessor method addItem() in Dict I add
the instances of Item to Dict. In this case I add Item1 and Item2 to
Dict1 and I add Item3 and Item4 to Dict2. When this is done I print
out the instances of Dict and of Item. It appears that the dictionary
items in each of the Dict instances is the exact same instance even
though they were created as distinctly separate classes. The print out
of the results shows them at the same memory address. The items
dictionary inside of each Dict object have the same id when I do
id(dict1.items) and id(dict2.items). This means that each of the items
dictionary in the Dict instances has all four items in it, even though
each should only have two. Apparently when I add the first to Item
instances to dict1 and then the second two Item instances to dict2 they
are being added to the same items dictionary.
By creating the attributes items and name in the body of class Dict, you
are creating class attributes which are shared by all instances of the
class. When addItem refers to self.items, it finds no instance
attribute, so it falls back to modifying the class attribute.

What you want to do instead is define

class Dict:
def __init__(self):
self.items = {}
self.name = ""
....

and similarly for Item

David


class Dict:
items = {}
name = ""

def addItem(self,item,name):
self.items[name] = item
def setName(self,name):
self.name = name

def getName(self):
return self.name

def printItemKeys(self):
print "Dictonary Keys: ",self.items.keys()


Jul 18 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.