Seite 1 von 1

[gelöst] Problem mit return

Verfasst: Sonntag 7. Januar 2007, 13:13
von BartSimpson
Hallo,
ich habe folgenden Code:

Code: Alles auswählen

import glob,string
def ZeileKorregierenFallsNoetig(zeile):
    #1. Suchzeichen: :/
    #2. Suchzeichen /
    #3. Suchzeichen das Nächste /
    Zeichen1=string.find(zeile,":/")
    Zeichen2=string.find(zeile,"/",Zeichen1+2)
    Zeichen3=string.find(zeile,"/",Zeichen2+2)
    #Wenn Zeichen3 -1 ist, wurde es nicht gefunden->Es kann kein Fehler geben
    if Zeichen3==-1:
        return False,""
    Fehler=zeile[(Zeichen1+2):Zeichen2+1]
    print "\tKorregiere Zeile:",zeile.lstrip()
    zeile=string.replace(zeile,Fehler,"",1)
    print "\tdurch:",zeile.lstrip()
    return True,zeile

for Dateiname in glob.glob("tmp/ui_header/*h"):
    print u"Prüfe", Dateiname
    Datei=open(Dateiname,"r")
    Puffer=""
    Korregiert=False
    for Zeile in Datei:
         #Die defekten Zeilen enthalten ->setIcon(
        if string.find(Zeile,"->setIcon(")!=-1:
            Korregiert,Korrektur=ZeileKorregierenFallsNoetig(Zeile)
            if Korregiert==True:
                Puffer=Puffer+Korrektur
            else:
                Puffer=Puffer+Zeile
    Datei.close()
    if Korregiert==True:
        print Puffer
        print "\tDatei wurde korregiert"
Nur leider klappt die Sache nicht, wenn die Funktion True zurück geben müste. Wenn die Bedingung wahr ist, wird

Code: Alles auswählen

if Korregiert==True:
        print Puffer
        print "\tDatei wurde korregiert"
leider nicht ausgeführt:(
Hat jemand eine Idee, was da schiefgeht?

Re: Problem mit return

Verfasst: Sonntag 7. Januar 2007, 15:56
von BlackJack
BartSimpson hat geschrieben:Nur leider klappt die Sache nicht, wenn die Funktion True zurück geben müste. Wenn die Bedingung wahr ist, wird

Code: Alles auswählen

if Korregiert==True:
        print Puffer
        print "\tDatei wurde korregiert"
leider nicht ausgeführt:(
Hat jemand eine Idee, was da schiefgeht?
`Korregiert` wird für jede Zeile der Eingabe an `True` oder `False` gebunden, je nach dem ob die Zeile verändert werden musste oder nicht. Das heisst an dieser Stelle sagt `Korregiert` nur aus ob die letzte bearbeitete Zeile verändert wurde und nicht ob irgend eine Zeile verändert wurde.

Weitere Anmerkungen zum Quelltext: Die Namen sind nicht PEP8 konform. Um binäre Operatoren sollte man Leerzeichen setzen, sowie nach Kommata. Vergleiche auf ``xyz == True`` oder ``xyz == False`` sind redundant wenn `xyz` selbst schon als Wahrheitswert genommen werden kann.

Zeichenketten sind "immutable" das heisst bei jeder "addition" von Zeichenketten wird eine neue angelegt und die beiden alten Inhalte dorthin kopiert. Den `Puffer` auf diese Art aufzubauen ist ineffizient. Üblicherweise nimmt man dafür eine Liste die man am Ende mit der `join()`-Methode von Zeichenketten zu einer grossen Zeichenkette zusammenfügt. Man kann diese Liste aber auch mit der `writelines()`-Methode von Dateiobjekten ausgeben. Im Falle der Konsolenausgabe also auf `sys.stdout`.

Die meisten Funktionen im `string`-Modul sind veraltet, man benutzt stattdessen die entsprechenden Methoden auf Zeichenketten-Objekten.

Die Korrekturfunktion würde ich so ändern, dass kein Tupel zurückgegeben wird, sondern immer nur eine Zeile. Wenn keine Veränderungen vorgenommen wurden, dann einfach die unveränderte Zeile zurückgeben. Der Test ob "->setIcon(" in der Zeile enthalten ist, sollte auch in die Korrekturfunktion wandern und mit dem ``in``-Operator formuliert werden. Also:

Code: Alles auswählen

if '->setIcon(' in zeile:
    # ...
Dann ist das Programm etwas einfacher und verständlicher.

Wenn wirklich das selbe Zeichenketten-Objekt von der Korrekturfunktion zurückgegeben wird, falls keine Veränderung vorgenommen wurde, dann lässt sich die Veränderung auch effizient mit dem ``is``-Operator überprüfen. Die Leseschleife könnte dann so aussehen:

Code: Alles auswählen

result = list()
unchanged = True
for line in in_file:
    processed_line = zeile_korregieren_falls_noetig(line)
    result.append(processed_line)
    unchanged &= line is processed_line

Verfasst: Sonntag 7. Januar 2007, 16:44
von BartSimpson
Danke jetzt klappt es auch:)