在构造函数中迭代 return

Iterated return in constructors

为什么这个例子 return 只有最后 child 个属性,我怎样才能得到它们?

输入:

    <root c1="A" c2="B"</root>
    <root c1="A" c2="C"</root>

脚本:

    data = ElementTree.parse("./test.xml").getroot()
    def getLetters(data):
        for child in data:
            if child.attrib['c1']:
               c1 = child.attrib['c1']
            if child.attrib['c2']:
               c2 = child.attrib['c2']
        return c1, c2
    print getLetters(data)

结果总是被覆盖,我得到最后一个child。

我试过 yield 但还是有同样的问题:

       yield c1, c2
   generator = getLetters(data)
   for i in generator:
       print i

您在函数中所做的是遍历您碰巧在 xml 中拥有的所有元素对。完成迭代后,您 return 最终分配给 c1 和 c2 的任何值(甚至可能不是来自相同的 child,您的代码编写方式),这将是最后一个一对元素或 c1 和 c2 对应于它们在 xml 中的最后一次出现(因为您没有对先前获得的值对执行任何操作)。

这里有两种方法:

1) 创建结构,例如元组列表,或者更好的是,字典,并继续在其中添加 (c1, c2) 元素:

def getLetters(data):
    result = []
    for child in data:
        # use other default values here if more suitable 
        c1 = None
        c2 = None
        if child.attrib['c1']:
           c1 = child.attrib['c1']
        if child.attrib['c2']:
           c2 = child.attrib['c2']
        result.append({'c1':c1, 'c2':c2}) # append your next entry as a mini-dictionary  
    return result

for entry in getLetters(data):
    print 'c1', entry['c1'], 'c2', entry['c2']

2) 使用 yield 这可能是处理大量数据的更有效方法,因为您不必等到所有数据都处理完毕再进一步传递。

def getLetters(data):
    for child in data:
        # use other default values here if more suitable 
        c1 = None
        c2 = None
        if child.attrib['c1']:
           c1 = child.attrib['c1']
        if child.attrib['c2']:
           c2 = child.attrib['c2']
        yield {'c1':c1, 'c2':c2} # yield the mini-dictionary for every child
    # no return needed here

# you can process the output in the same way:
for entry in getLetters(data):
    print 'c1', entry['c1'], 'c2', entry['c2']
    class getLetters:
          def __init__(self):
              self.c1 = child.attrib['c1']
              self.c2 = child.attrib['c2']

    for child in data:
        i = getLetters()
        c1 = i.c1
        c2 = i.c2
        print c1, c2