Dateien öffnen

Code-Stücke können hier veröffentlicht werden.
Antworten
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Wenn man ein Programm schreibt, das viele dateien öffnet und schreibt, nervt der das unnötige schreiben oft. Deshalb hab ich zwei funktionen geschrieben die das in einem zug machen, und möchte gern wissen was ihr davon haltet:

Code: Alles auswählen

def fileopen(path):
    try:
        f=open(path, 'r')
        dtt=f.read()
        f.close()
        return(dtt)
    except:
        return('Fehler')
und

Code: Alles auswählen

def filesave(path, dateiinhalt):
    try:
        f=open(path, 'w')
        dtt=f.write(dateiinhalt)
        f.close()
    except:
        return('Fehler')
Zuletzt geändert von Py-Prog am Samstag 3. Juli 2010, 16:23, insgesamt 2-mal geändert.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
BlackJack

@Py-Prog: Ein paar Namen sind falsch. `fileopen()` öffnet zum Beispiel nicht sondern liest ein. Das `datei`-Argument bei `filesave()` ist keine Datei sondern Datei*inhalt*.

Und die Ausnahmebehandlung ist unsinnig. Ausnahmen sollte man nur behandeln wenn man das auch *sinnvoll* tun kann. Eine Ausnahme in einen "speziellen" Rückgabewert verwandeln ist nicht sinnvoll, denn Ausnahmen wurden ja gerade eingeführt um diese speziellen Fehlerwerte loszuwerden. Insbesondere bei `fileopen()` ist der Rückgabewert noch nicht einmal speziell. Wie unterscheide ich denn bitte einen Fehler von einer Textdatei die *tatsächlich* 'Keine Datei' oder 'Fehler' als Text enthält und fehlerfrei gelesen werden konnte!? Zumal 'Keine Datei' bei einem `IOError` unzutreffend sein kann. Ein-/Ausgabefehler können durch eine ganze Reihe von gegebenheiten entstehen, nicht nur wenn die Datei nicht existiert.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

BlackJack hat geschrieben:@Py-Prog: Ein paar Namen sind falsch. `fileopen()` öffnet zum Beispiel nicht sondern liest ein. Das `datei`-Argument bei `filesave()` ist keine Datei sondern Datei*inhalt*.
Genau das wolte ich ja.
BlackJack hat geschrieben: Und die Ausnahmebehandlung ist unsinnig. Ausnahmen sollte man nur behandeln wenn man das auch *sinnvoll* tun kann. Eine Ausnahme in einen "speziellen" Rückgabewert verwandeln ist nicht sinnvoll, denn Ausnahmen wurden ja gerade eingeführt um diese speziellen Fehlerwerte loszuwerden. Insbesondere bei `fileopen()` ist der Rückgabewert noch nicht einmal speziell. Wie unterscheide ich denn bitte einen Fehler von einer Textdatei die *tatsächlich* 'Keine Datei' oder 'Fehler' als Text enthält und fehlerfrei gelesen werden konnte!? Zumal 'Keine Datei' bei einem `IOError` unzutreffend sein kann. Ein-/Ausgabefehler können durch eine ganze Reihe von gegebenheiten entstehen, nicht nur wenn die Datei nicht existiert.
Wenn ich die Ausnahmen nicht mache beendet sich das Programm wenn die Datei nicht existiert, und das ist ganz schlecht wenn, ein Das skript keine fehlermeldungen ausgiebt wenn ein fehler unterlaufen ist, weil man dann z. B. denkt die Backups sind ervolgreich abgeschlossen obwohl das Skript sich vorzeitig beendet hat.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Code: Alles auswählen

~# python -c "raise IOError()" && echo success
Traceback (most recent call last):
  File "<string>", line 1, in <module>
IOError
Es wird eine Fehlermerldung ausgegeben und der Returncode zeigt einen Fehler an, wie kann man da von erfolgreich sprechen?

P.S.: return ist ein Keyword und keine Funktion.
BlackJack

@Py-Prog: Was genau wolltest Du ja? Falsche Namen verwenden? Wie unsinnig ist dass denn?

Wenn eine Ausnahme das Programm beendet, dann fehlt eine Ausnahmebehandlung. Aber an der richtigen Stelle und das ist sicher nicht in *den* beiden Funktionen. Das *erhöht* sogar die Gefahr dass ein Programm sich normal beendet obwohl ein Fehler aufgetreten ist, denn genau das ist ja eines der Probleme mit speziellen Fehlerwerten, das man mit Ausnahmen beheben möchte: Es ist nicht mehr so einfach möglich Fehler zu ignorieren. Bei Fehlerwerten ist es ganz einfach den Wert zu ignorieren in dem man einfach keinen Code schreibt, der ihn prüft. Bei Ausnahmen muss man wenigstens aktiv und absichtlich sagen, dass einem der Fehler egal ist, sonst fliegt er einem um die Ohren.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Das Schließen der Datei sollte außerdem im finallay erfolgen

Code: Alles auswählen

try:
     f = open(iwas, 'w')
     #bla
finally:
    f.close()
oder gleich mit dem with Statement öffnen

Code: Alles auswählen

with open(iwas, 'w') as f:
    pass
the more they change the more they stay the same
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

@Dav1d: Du machst dort zwei verschiedene Dinge:

Code: Alles auswählen

>>> try:
...     f = open(42)
... finally:
...     f.close()
... 
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
NameError: name 'f' is not defined
>>> with open(42) as f:
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: coercing to Unicode: need string or buffer, int found
Beide mögliche Fehlerquellen müssen behandelt werden.
Das Leben ist wie ein Tennisball.
lunar

"open" kann und sollte vor den Block gezogen werden. Wenn die Datei nicht geöffnet werden konnte, braucht man auch kein finally, um sie wieder zu schließen. Das ist nur bei Fehlern nötig, die nach dem Öffnen auftreten:

Code: Alles auswählen

stream = open(foo, 'w')
try:
    stream.write('hello world')
finally:
    stream.close()
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich halte es nicht für nötig, das Lesen und Schreiben von Textdateien gesondert als Hilfsfunktionen zu extrahieren, denn die Logik ist so einfach, dass es einfach genug ist, das in jeder Anwendung selbst zu machen. Zudem gilt es häufig besondere Bedürfnisse eines Programms zu beachten und auch das Verhalten, wenn die Datei existiert oder nicht, kann jedes Mal anders sein.

Dass das `return 'Fehler'` keine gute Idee ist, haben schon andere geschrieben. Wenn man's unbedingt in Funktionen gießen will, würde ich folgendes vorschlagen:

Code: Alles auswählen

def file_read(n):
    with open(n, "r") as f: return f.read()

def file_write(n, d):
    with open(n, "w") as f: f.write(d)
Meist ist es aber besser, Textdateien nicht komplett zu lesen, sondern sie zeilenweise zu verarbeiten.

Will man sie nur mal kurz in einem "Wegwerfprogramm" verarbeiten, finde ich es auch akzeptabel, die Ressourcen nicht korrekt zu schließen (passiert bei `with` implizit), sondern sich darauf zu verlassen, dass der CPython-Interpreter das dank Referenz-Zählung selbstständig macht und würde einfach dies benutzen:

Code: Alles auswählen

t = open(n).read()
open(n, "w").write(t)
Dazu sollte man aber die erste korrekte Version verstanden haben.
Stefan
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

lunar hat geschrieben:"open" kann und sollte vor den Block gezogen werden. Wenn die Datei nicht geöffnet werden konnte, braucht man auch kein finally, um sie wieder zu schließen. Das ist nur bei Fehlern nötig, die nach dem Öffnen auftreten:
EyDu, lunar: Ja, da habt ihr natürlich recht
the more they change the more they stay the same
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Ist der

Code: Alles auswählen

def fileopen(path):
    f=open(path, 'r')
    dtt=f.read()
    f.close()
    return dtt
    
und der

Code: Alles auswählen

def filesave(path, dateiinhalt):
    f=open(path, 'w')
    dtt=f.write(dateiinhalt)
    f.close()
    
besser als mein erster vorschlag?
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
lunar

Unwesentlich. Zwar hast Du die unsinnige Ausnahmebehandlung entfernt, aber korrekt geschlossen werden die Dateien im Falle einer Ausnahme noch immer nicht.

Und letztlich hat sma recht. Das ist viel zu trivial, um eine eigene Hilfsfunktion zu rechtfertigen.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Ihr hattet recht, mit dieser

Code: Alles auswählen

return 'Fehler'
anweisung sucht man den fehler an der faltschen stelle.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Stell dir mal vor, die Datei enthält Fehler! ;)
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Antworten