Python bug with dictionary

Discussion in 'Python' started by none, Jul 22, 2003.

  1. none

    none Guest

    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
    none, Jul 22, 2003
    #1
    1. Advertising

  2. none

    David C. Fox Guest

    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()
    >
    David C. Fox, Jul 22, 2003
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ilias Lazaridis
    Replies:
    6
    Views:
    437
    Ilias Lazaridis
    Feb 21, 2006
  2. james_027
    Replies:
    1
    Views:
    322
    Marc 'BlackJack' Rintsch
    Aug 22, 2007
  3. Navkirat Singh
    Replies:
    6
    Views:
    3,026
    Navkirat Singh
    Jul 29, 2010
  4. Chris Rebert
    Replies:
    0
    Views:
    521
    Chris Rebert
    Jul 29, 2010
  5. Fox

    dictionary within dictionary

    Fox, Mar 8, 2005, in forum: ASP General
    Replies:
    5
    Views:
    183
    Michael D. Kersey
    Mar 13, 2005
Loading...

Share This Page