2009-08-10 4 views
3

Ich habe ein Python-Skript, das eine Datei Zeile für Zeile verarbeiten, wenn die Zeile eine Regex entspricht, ruft es eine Funktion auf, um es zu behandeln.Benötigen Sie Hilfe beim Refactoring meines Python-Skripts

Meine Frage ist, gibt es eine bessere schreiben Refactor mein Skript. Das Skript funktioniert, aber so wie es ist, muss ich den Einzug rechts vom Editor beibehalten, da ich mehr und mehr Regex für meine Datei hinzufüge.

Vielen Dank für eine Idee. mein Code nun bis am Ende wie folgt:

 
for line in fi.readlines(): 

     result= reg1.match(line) 

     if result: 
       handleReg1(result) 

     else: 
       result = reg2.match(line) 

       if result: 
         handleReg2(result) 
       else: 
         result = reg3.match(line) 

         if result: 
           handleReg3(result) 
         else: 
           result = reg4.match(line) 

           if result: 
             handleReg4(result) 
           else: 
             result = reg5.match(line) 

             if result: 
               handleReg5(result) 
+4

Jeder Grund, warum Sie elif vermeiden? – balpha

Antwort

12

ich unter Verwendung einer Datenstruktur Mapping Regexes auf Funktionen wechseln würde. Etwas wie:

map = { reg1: handleReg1, reg2: handleReg2, etc } 

Dazu einfach Schleife durch sie:

for reg, handler in map.items(): 
    result = reg.match(line) 
    if result: 
     handler(result) 
     break 

Wenn Sie die Spiele müssen in einer bestimmten Reihenfolge geschehen müssen Sie eine Liste verwenden, anstatt eines Wörterbuchs, aber die Prinzip ist das Gleiche.

+0

Dies ist der Ansatz, den ich auch empfehlen würde. Wie bereits erwähnt, sollten Sie eine Liste verwenden, wenn Sie eine bestimmte Reihenfolge benötigen - wahrscheinlich so etwas wie 'handlers = [(reg1, handleReg1), (reg2, handleReg2), ...]' und dann würde Ihre for-Schleife aussehen wie folgt: 'for (reg, handler) in Handlern:' – Amber

+1

Sie wollen definitiv eine Liste und kein Wörterbuch. Es gibt hier keinen Schlüssel-Lookup - es ist nur eine Verbindung zwischen einer Regex und einer Funktion. Eine Liste von Tupeln wäre gut. – hughdbrown

1

Hier ist trivial:

handlers = { reg1 : handleReg1, ... } 

for line in fi.readlines(): 
    for h in handlers: 
     x = h.match(line) 
     if x: 
      handlers[h](x) 

Wenn es eine Linie sein könnte, dass dieser Code mehrere regexps entspricht, wird aus dem Code unterschiedlich sein Sie eingefügt: es wird mehrere Handler aufrufen. Das Hinzufügen von break wird nicht helfen, weil die Regexps in einer anderen Reihenfolge ausprobiert werden, so dass Sie am Ende die falsche aufrufen werden. Also, wenn dies der Fall ist, sollten Sie über die Liste iterieren:

handlers = [ (reg1, handleReg1), (reg2, handleReg2), ... ] 

for line in fi.readlines(): 
    for reg, handler in handlers: 
     x = reg.match(line) 
     if x: 
      handler(x) 
      break 
+0

Das ist nicht identisch; Ihr Weg könnte mehrere Handler anrufen; seine ruft höchstens eins. – balpha

+0

Die obige Version ist auch nicht identisch, da es Regexps versuchen kann, anders als reg1, reg2, ... –

0

Ein alternativer Ansatz, die funktionieren könnte für Sie ist es, alle regexps in einem riesigen regexp zu kombinieren und nutzen m.group() zu erkennen, welche abgestimmt. Meine Intuition sagt, das sollte schneller sein, aber ich habe es nicht getestet.

Dies wird kompliziert, wenn die Regexps, gegen die Sie testen, selbst kompliziert sind oder Match-Gruppen verwenden.

+0

Es ist sehr schnell, und das Mittel gegen innere Regexps, die komplex sind und Match-Gruppen verwenden, ist benannte Gruppen um sie herum (in einem "Namespace", z. B. mit einem Präfix, von allen benannten Gruppen, die von inneren Regexps verwendet werden können, dijoint). –

Verwandte Themen