Question

I have an xml of following type:

<?xml version="1.0" encoding="UTF-8"?>
<RootNode>
<childElem>
<prop1 type="int">1</prop1>
<prop2 type="int">2</prop2>
</childelem>
<childElem>
<prop1 type="int">3</prop1>
<prop2 type="int">4</prop2>
</childelem>
<childElem>
<prop1 type="int">5</prop1>
<prop2 type="int">6</prop2>
</childelem>
<childElem>
<prop1 type="int">7</prop1>
<prop2 type="int">8</prop2>
</childelem>
</RootNode>

I have defined class to store all child elements as different instance of the class. I am trying to append the objects in a list and then retrieving.

in this xml there are total 4 childelem. I have printed the properties of each object after creating each object. There I am seeing each object has different property values.

But after that when I am trying to retrieve each object from the list in a for loop and printing properties of each retrieved object, it's printing last childelem object four times.

Here is the code snippet

def getObjects(self,xmlStr,elem):
    objList = []
    root = ET.fromstring(xmlStr)
    rootNode = root.find(elem)
    for obj in rootNode.findall('childElem'):
        myObj = Obj()
        for props in obj:
            myObj.populate(props.tag,props.text)
        print(">>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<")
        print(myObj.getProps())
        print(">>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<")
        objList.append(myObj)

    for obj1 in objList:
        print(obj1.getProps())
        print("@@@@@@@@@@@@@@@@@@@@@@@@@@")
    return objList
class Obj:
    properties = {}

    def populate(self,name,value):
        self.properties[name] = value
    def getProps(self)
        return self.properties

I am new to Python, can some one explain what is wrong? Why in the retrieval for loop only last childElem is coming four times? How can I rectify the error?

here is the out put

>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<
{'prop1': '1', 'prop2': '2'}
>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<
{'prop1': '3', 'prop2': '4'}
>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<
{'prop1': '5', 'prop2': '6'}
>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<
{'prop1': '7', 'prop2': '8'}
>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<
{'prop1': '7', 'prop2': '8'}
@@@@@@@@@@@@@@@@@@@@@@@@@@
{'prop1': '7', 'prop2': '8'}
@@@@@@@@@@@@@@@@@@@@@@@@@@
{'prop1': '7', 'prop2': '8'}
@@@@@@@@@@@@@@@@@@@@@@@@@@
{'prop1': '7', 'prop2': '8'}
@@@@@@@@@@@@@@@@@@@@@@@@@@
Was it helpful?

Solution

You are sharing a mutable dictionary on the class between the different instances of Obj. If you change it to be an instance variable (by setting self.properties in Obj.__init__), the code should work as you'd like:

class Obj:

    def __init__(self):
        self.properties = {}

    # The rest of Obj's methods.

As it stands, your code creates one dictionary, Obj.properties (which is still accessible via self.properties on an instance). Then the myObj.populate calls each update that one dictionary, so the details for the last element are printed 4 times.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top