2017-05-12 9 views
0

Ich möchte die Funktionalität der for-Schleife umhüllen, so dass es intuitiver wäre, es zu verwenden. In meinem Fall, ich habe xml-Datei analysieren sieht wie folgt aus:Wrapping für Schleife in 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> 

ich eine Klasse für Instance wie folgt geschrieben:

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

ich die nächste Funktion schrieb die Instanzen aufzuzählen:

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) 
     ) 

der action Parameter ist ein Rückruf eine Aktion mit dem Instance, wie dies zu tun:

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

aber es sieht ein wenig seltsam, ich möchte es noch intuitiver sein, wie folgt aus:

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

was ist die beste Art und Weise, dass ‚iterable‘ Funktion zu implementieren? Dank

+2

Warum also nicht tun genau das, was Sie wollen, dann? Rufen Sie nicht Aktion ... stattdessen ... 'erben 'die Instanz ... –

+0

BTW, diese XML-Datei ist nicht XML. Es muss eine einzelne Wurzel geben. –

+0

@ polkovnikov.ph Sie haben Recht, es gibt eine Wurzel und eine chaotische Struktur für mein XML, aber ich habe nur den relevanten Teil für die Frage –

Antwort

1

Statt eine aufrufbare auf Ihre Funktion vorbei, machen es zu einem Instance ergeben, dann können Sie das Verhalten erhalten Sie wollen, zB:

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 

In diesem Fall - ich habe action-None vorbelegt , aber es lässt Ihnen Raum, um eine Funktion zu übergeben, um die instance irgendwie vor yield zu wandeln, wenn es erforderlich ist.

Dann:

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

Ich denke, Sie schlagen mich einfach - haben Sie eine zusätzliche paren nach 'Text) 'Auf der letzten Zeile? – doctorlove

+0

@doctorlove Ich tat tatsächlich - guten Platz. –

3

Generatoren für den Sieg, in diesem Fall. So etwas wie

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) 

Dann können Sie genau sagen, was Sie benötigen:

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