Python lxml: странная проблема с чтением повторяющихся элементов и сохранением в списке - PullRequest
2 голосов
/ 26 апреля 2011

У меня странная проблема. У меня было две очень разные версии кода для решения одной и той же проблемы, и я столкнулся с одной и той же проблемой.

Я упростил задачу до этого:

Вот XML-файл:

<Test>
 <Object name="Ob1">
  <List/>
 </Object>

 <Object name="Ob2">
  <List>
   <item>One</item>
   <item>Two</item>
  </List>
 </Object>

 <Object name="Ob3">
  <List>
   <item>Three</item>
   <item>Four</item>
   <item>Five</item>
  </List>
 </Object>
</Test>

Вот код Python:

from lxml import etree

#Load XML

fileobject = open("list_test.xml", "r") #read-only
parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse(fileobject, parser)
root = tree.getroot()

object_list = []

class TestClass():
    name = None
    list = []


for OB in root:
    temp_ob = TestClass()
    temp_ob.name = OB.get("name")
    for SubElem in OB:
        if SubElem.tag == "List":
            for item in SubElem:
                if item.tag == "item":
                    temp_ob.list.append(item.text)
    object_list.append(temp_ob)
    del temp_ob

for ob in object_list:
    print ob.name
    print ob.list

Код должен хранить все элементы <item> в списке в объекте, который сам хранится в списке.

Однако вот что я получаю:

Ob1
['One', 'Two', 'Three', 'Four', 'Five']
Ob2
['One', 'Two', 'Three', 'Four', 'Five']
Ob3
['One', 'Two', 'Three', 'Four', 'Five']

Почему он получает все элементы <item> во всем документе?

1 Ответ

2 голосов
/ 26 апреля 2011

TestClass.list является атрибутом уровня класса , поэтому каждый object_list.append() находится в одном и том же списке.

Например:

class Foo(object):
    lst = []

f1 = Foo()
f1.lst.append(1)
f2 = Foo()
f2.lst.append(2)
print f1.lst
print f2.lst

[1, 2]
[1, 2]

Вы должны сделать его атрибутом уровня экземпляра :

class Bar(object):
    def __init__(self):
        self.lst = []

b1 = Bar()
b1.lst.append(1)
b2 = Bar()
b2.lst.append(2)
print b1.lst
print b2.lst

[1]
[2]
...