2017-05-12 40 views
0

我想包装for循环的功能,所以它会更直观地使用它。在我的情况,我要解析的XML文件是这样的:在python中循环包装

<instance id="line-n.w8_047:15696:"> 
    <answer instance="line-n.w8_047:15696:" senseid="product" /> 
    <context> context1 </context> 
</instance> 

<instance id="line-n.w8_088:12441:"> 
    <answer instance="line-n.w8_088:12441:" senseid="product" /> 
    <context> another context</context> 
</instance> 

我写了一个类Instance这样的:

class Instance: 
    def __init__(self, id, answer, context): 
     self.id = id 
     self.answer = answer 
     self.context = context 

我写了下面的函数来列举实例:

import xml.etree.ElementTree as ET 
def enum_instances(file_path, action): 
    for instance_xml in ET.parse(file_path).getroot().find('lexelt'): 
     action(Instance(
      instance_xml.attrib['id'], 
      instance_xml.find('answer').attrib['senseid'], 
      instance_xml.find('context').text) 
     ) 

action参数是一个回调,用Instance做一些动作,像这样:

enum_instances('/path/to/xml', lambda instance: print(instance.context)) 

,但它看起来有点奇怪,我想它更直观,就像这样:

for instance in enum_instances(file_path): 
    print(instance.context) 

什么是实现“迭代”功能的最佳方法是什么? 感谢

+2

那么为什么不这样做只是你想要什么呢?不要调用动作......而是......“yield”实例... –

+0

顺便说一句,该XML文件不是XML。必须有一个根。 –

+0

@ polkovnikov.ph你说得对,我的XML有一个根和一个凌乱的结构,但我只提出了相关部分的问题 –

回答

1

不是传递一个可调用你的功能,使之产生一个Instance,那么你就可以得到你想要的行为,如:

def enum_instances(file_path, action=None): 
    for instance_xml in ET.parse(file_path).getroot().find('lexelt'): 
     instance = Instance(
      instance_xml.attrib['id'], 
      instance_xml.find('answer').attrib['senseid'], 
      instance_xml.find('context').text) 
     if action is not None: 
      instance = action(instance) 
     yield instance 

在这种情况下 - 我已经拖欠actionNone ,但是如果需要的话,它会给你留出空间来通过函数来​​改变instanceyield之前的变化。

然后:

for instance in enum_instances('some_file_path'): 
    print(instance.context) 
+0

我想你只是把它打败了 - 你在文本之后有多余的文件) '在最后一行? – doctorlove

+0

@doctorlove我确实 - 很好的地方。 –

3

发电机为胜,在这种情况下。像

def enum_instances(file_path): 
    for instance_xml in ET.parse(file_path).getroot().find('lexelt'): 
     yield Instance(
      instance_xml.attrib['id'], 
      instance_xml.find('answer').attrib['senseid'], 
      instance_xml.find('context').text) 

东西然后你就可以说,正是你需要什么:

for instance in enum_instances(file_path): 
    print(instance.context)