Datei öffnen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Bl3nder
User
Beiträge: 113
Registriert: Freitag 3. Januar 2020, 17:07

Montag 10. Mai 2021, 18:42

Hallo Leute,

Ich hätte eine ganz kurze Frage und zwar geht es um das öffnen von Datei -> Suchfunktion habe ich genutzt aber leider keine Antwort auf mein Problem.



Oft habe ich gelesen das empfohlenwird :

Code: Alles auswählen

with open("a.txt") as f:
    print f.readlines()
aber wieso in dem Fall würden doch trotzdem noch nicht alle Exception abgefangen werden Ich wollte gerne einen Weg lernen den Ich verinnerlichen.



1.) o.g Code

2.)

Code: Alles auswählen

try:
    with open("a.txt") as f:
        print(f.readlines())
except Exception as error: 
    print('oops')

3.)with ganz weg lassen und alles selber machen

Code: Alles auswählen

try:
   # log file to write to
   logFile = r'path\tofile\fileName.txt'

   # open file in write mode
   report = open(logFile, 'w')

   # geoprocessing stuff

   # write to report
   report.write('some message')

except Exception as e:
   # get line number and error message
   report.write('an error message')

finally:
   report.close()

Ich bin deswegen ein bisschen verwirrt da es für mich kein Grund gibt eine Datei mit with nur zu öffnen und zu schließen und wenn ein Fehler auftritt diesen nicht beheben zu wollen ?


Ich danke euch
Eine Vision ohne Aktion bleibe eine Illusion
Sirius3
User
Beiträge: 14583
Registriert: Sonntag 21. Oktober 2012, 17:20

Montag 10. Mai 2021, 19:07

Du merkst ja selbst, dass die dritte Variante deutlich komplizierter ist. Und trotzdem hast Du die Fehlerbehandlung nicht ganz korrekt umgesetzt.

with hat nichts mit Exceptions zu tun, sondern mit dem Aufräumen im Fehlerfall. Wie Du Exceptions behandelst, kommt ganz darauf an, was Du genau machst.
Benutzeravatar
noisefloor
User
Beiträge: 3185
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: Görgeshausen
Kontaktdaten:

Montag 10. Mai 2021, 19:09

Hallo,

das eine hat mit dem anderen nichts zu tun. Das `with` Statement kümmert sich darum, dass die Datei auf jeden Fall wieder geschlossen wird. Mit Exception-Handling hat `with` nichts zu tun. Außer halt, dass die Datei geschlossen wird, wenn die Exception geworfen wird.

Sprich, um das Abfangen von Fehlern musst du dich nach wie vor selber kümmern. Nackte `try...except` wie in deinem Beispiel möchte man eigentlich so gut wie nie verwenden, weil du damit stumpf _alle_ Fehler abfängst, auch Programmierfehler. Fehler fängt man i.d.R. gezielt ab.

Details zu with siehe Doku oder für die volle Tiefe PEP343

Gruß, noisefloor
Bl3nder
User
Beiträge: 113
Registriert: Freitag 3. Januar 2020, 17:07

Montag 10. Mai 2021, 19:42

Für mich wäre Beispiel 2 am besten dort würde Ich dann nur alle exception abfangen Filenotfound etc .... und dort versuchen dieses zu beheben in dem die die Datei erstellen oder ähnliches .... Ich bekomme einfach die Try Except Gesichte nicht in meinem Kopf .... könnt Ihr mir mal ein Beispiel zeigen wie Ihr eine handelsübliche Datei öffnen würdet?


Oder eine andere Frage dazu mal angenommen macht man sowas auch ?

Mal angenommen Ich möchte das Problem nicht in der funktion behandeln das Ich dann nochmal den Fehler raise damit Ich diesen auf der main ebene bearbeitete ? Oder wie macht dann sowas ? Mir ist gerade kein besserers Beispiel eingefallen mir ist auch bewusstet das das Schwachsinn ist da Ich mir das Try Except in der Funktion so sparen könnte das es beides mal das gleiche ist mir geht es da ehr um die allgemeine Veranschaulichung

Code: Alles auswählen

def file_open():
    pfad = Path(r"C:\Users\Marcel\Desktop\zahlen.txt.txt")
    try:
        with open("a.txt") as f:
            print(f.readlines())
    except FileExistsError: 
        raise FileExistsError

def main():
    try:
        file_open()
    except FileExistsError:
        print("behandeln des Fehlers...")
if __name__ == "__main__":
    main()
Eine Vision ohne Aktion bleibe eine Illusion
Benutzeravatar
__blackjack__
User
Beiträge: 8716
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Montag 10. Mai 2021, 20:54

@Bl3nder: Ein `FileExistsError` dürfte bei einer Datei die zum Lesen geöffnet wird *sehr* unwahrscheinlich sein. Das Beispiel lässt sich also Deutlich verkürzen. 😉

`pfad` wird definiert, aber nirgends verwendet.

Und solange man nicht weiss welche Ausnahme wie *sinnvoll* behandelt werden soll, behandelt man die einfach gar nicht.

Code: Alles auswählen

#!/usr/bin/env python3


def file_open():
    with open("a.txt") as file:
        print(list(file))


def main():
    file_open()


if __name__ == "__main__":
    main()
long long ago; /* in a galaxy far far away */
Bl3nder
User
Beiträge: 113
Registriert: Freitag 3. Januar 2020, 17:07

Dienstag 11. Mai 2021, 05:23

@__Blackjack__ ich danke dir ok dann werde ich in Zukunft erstmal nur das Projekt schreiben und beim Testen auf try except zugreifen . Ich glaube ich mache mir schon vorher zu viele Gedanken was alles theoretisch passieren könnte nochmal danke an alles dir geholfen haben :)
Eine Vision ohne Aktion bleibe eine Illusion
Sirius3
User
Beiträge: 14583
Registriert: Sonntag 21. Oktober 2012, 17:20

Dienstag 11. Mai 2021, 05:46

Nein. Man macht sich schon theoretische Gedanken, welche Exceptions auftreten können, aber nur, wenn man sie sinnvoll behandeln kann.
Das ist bei so abstrakten Beispielen immer schwierig, weil sie meist an sich keinen tieferen Sinn haben.
Bl3nder
User
Beiträge: 113
Registriert: Freitag 3. Januar 2020, 17:07

Mittwoch 12. Mai 2021, 20:32

Tut mir leid das Ich das Thema nochmal aufgreife -> In dem Forum wird ja immer gesagt man soll Exceptions dort abfangen wo Sie sinnvoll sind ,aber wo ist es sinnvoll ( wird in den meisten Fällen so im Internet gezeigt) dann einfach nur eine Fehlermeldung zu printen Ich meine in dem Fall hat man den Fehler ja nicht richtig behandelt so würde ein Beispiel für mich aussehen wenn man ein Fehler behandelt : ( Ist jetzt nicht ganz perfekt mir geht es darum das Ihr meine Denkweise nachvollziehen könnt:

Code: Alles auswählen

from pathlib import Path


def forum_pfad():
    test_datei = Path("datei_gibt_es_nicht.txt")
    inhalt = None
    try:
        with open(test_datei) as file_obj:
            inhalt = file_obj.readlines()
    except FileNotFoundError:
        print(f"{test_datei},konnte nicht gefunden werden")
        nutzer_entscheidung = ""
        while nutzer_entscheidung != "nein":
            alternativer_pfad = None
            nutzer_entscheidung = input("Moechten Sie einen anderen Pfad versuchen ja/nein:")
            if nutzer_entscheidung == "ja":
                alternativer_pfad = input("Bitte geben Sie einen alternativen Pfad ein:")
                print(alternativer_pfad)
                alternativer_pfad = Path(alternativer_pfad)
                if alternativer_pfad.exists():
                    with open(alternativer_pfad) as file_obj:
                        inhalt = file_obj.readlines()
                    break
    finally:
        if inhalt != None:
            print(inhalt)


def main():
    forum_pfad()


if __name__ == "__main__":
    main()
Wie denkt ihr über sowas ?

Ich danke euch
Eine Vision ohne Aktion bleibe eine Illusion
Sirius3
User
Beiträge: 14583
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 12. Mai 2021, 21:08

Codewiederholungen sind schlecht. Du hast den Code zum Lesen der Datei doppelt. Dabei wird beim zweiten Lesen gar keine Exception abgefangen, sondern die Existenz per if abgefragt. Warum die unterschiedliche Behandlung?
Variablen mit Dummy-Werten zu belegen, ist schlecht. Das betrifft sowohl das `inhalt = None`, das später geprüft werden muß, ob eine Datei geladen wurde, und auch das `nutzer_entscheidung = ""` nur damit die while-Schleife starten kann. Das `alternativer_pfad = None` ist ganz überflüssig.
Die eine Funktion erledigt zu viele verschiedene Aufgaben: das Lesen einer Datei, das Fragen des Nutzers nach einer Ja-Nein-Entscheidung und das Fragen nach einem Dateinamen.
Das sollte man in mehrere Funktionen aufteilen, dann ist die Verschachtelung auch nicht so tief.

Code: Alles auswählen

def ja_nein_abfragen():
    while True:
        nutzer_entscheidung = input("Moechten Sie einen anderen Pfad versuchen ja/nein:")
        if nutzer_entscheidung == "ja":
            return True
        elif nutzer_entscheidung == "nein":
            return False


def forum_pfad():
    test_datei = Path("datei_gibt_es_nicht.txt")
    while True:
        try:
            with test_datei.open() as file:
                inhalt = list(file)
        except FileNotFoundError:
            print(f"{test_datei},konnte nicht gefunden werden")
        else:
            print(inhalt)
            break
        if not ja_nein_abfragen():
            break
        alternativer_pfad = input("Bitte geben Sie einen alternativen Pfad ein:")
        test_datei = Path(alternativer_pfad)
Bl3nder
User
Beiträge: 113
Registriert: Freitag 3. Januar 2020, 17:07

Mittwoch 12. Mai 2021, 21:21

Ich danke dir Ich glaube jetzt habe Ich es auch besser Verstanden :) nur noch eine allgemeine Frage:

1.)Mal angenommen du hättest keine Lösung für ein Problem und würdest das skript beenden wollen -> sys.exit(1) würdest du das auf Funktiontsebene machen oder das try Except Konstrukt in der main einbetten und dadrine die Funktion aufrufen und dort aus dem Skript dann gehen sprich:

Code: Alles auswählen

def main():
    try:
        forum_pfad()
    except FileNotFoundError:
        print("Fehler ....")
        sys.exit(1)
if __name__ == "__main__":
    main()
Eine Vision ohne Aktion bleibe eine Illusion
__deets__
User
Beiträge: 9846
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mittwoch 12. Mai 2021, 21:50

Niemals sys.exit lokal. Das verstehst du bei komplexeren Programmen nie mehr.
Bl3nder
User
Beiträge: 113
Registriert: Freitag 3. Januar 2020, 17:07

Mittwoch 12. Mai 2021, 22:45

Könntest du mir das eventuell veranschaulichen wenn eine Variable in eine Funktion deklariert wird ist diese ja lokal sprich ich soll sys.exit nicht in einer Funktion benutzen bzw. in meinem Fall mit meiner Main Funktion ??? Wie soll ich dann mein Programm vorher beenden in einem Fehlerfall
Eine Vision ohne Aktion bleibe eine Illusion
__deets__
User
Beiträge: 9846
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mittwoch 12. Mai 2021, 22:58

Du hast das Szenario doch selbst aufgemacht. Wenn du eine Ausnahme NICHT abfängst irgendwo tief im Code, weil du eh keine sinnvollen Umgang damit hast, perlt die nach oben, und du musst genau gar nix machen. Dein Programm beendet sich. Was genau also ist gewonnen, die irgendwo tief im Code lokal abzufangen & Exit aufzurufen?

Lokal heißt hier übrigens “an der Stelle wo sie passiert.” Das hat nichts mit lokalen oder globalen Variablen zu tun
Bl3nder
User
Beiträge: 113
Registriert: Freitag 3. Januar 2020, 17:07

Donnerstag 13. Mai 2021, 08:32

Was genau also ist gewonnen, die irgendwo tief im Code lokal abzufangen & Exit aufzurufen?
In dem Fall hast du Recht.Könntest du mir ein kleines Beispiel zeigen wo es dann überhaupt sinnvoll wäre sys.exit oder exit etc zu benutzen ?
Eine Vision ohne Aktion bleibe eine Illusion
Benutzeravatar
/me
User
Beiträge: 3434
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Donnerstag 13. Mai 2021, 08:43

Bl3nder hat geschrieben:
Donnerstag 13. Mai 2021, 08:32
Könntest du mir ein kleines Beispiel zeigen wo es dann überhaupt sinnvoll wäre sys.exit oder exit etc zu benutzen ?
exit soll laut Dokumentation in Programmen überhaupt nicht verwendet werden.

sys.exit benötigst du, wenn du einen Rückgabewert nach außen ans Betriebssystem (bzw. die Shell) geben möchtest. Das habe ich in über 15 Jahren Python-Programmierung genau einmal benötigt.
Antworten