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: 139
Registriert: Freitag 3. Januar 2020, 17:07

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: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

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: 3829
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

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: 139
Registriert: Freitag 3. Januar 2020, 17:07

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: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Bl3nder
User
Beiträge: 139
Registriert: Freitag 3. Januar 2020, 17:07

@__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: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

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: 139
Registriert: Freitag 3. Januar 2020, 17:07

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: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

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: 139
Registriert: Freitag 3. Januar 2020, 17:07

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: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

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

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: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

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: 139
Registriert: Freitag 3. Januar 2020, 17:07

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: 3552
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

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.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Die Verwendung von sys.exit ist sinnvoll bei Programmen, die von anderen Programmen als separate Prozesse aufgerufen werden, und an diese einen Statuscode zurück geben sollen. Konkrete Anwendungsfälle dafür können in der System-Administration liegen. Ansonsten bedarf es keines Aufrufs von sys.exit. Alle diesbezüglichen Beispiele, deren Anwendungen *nicht* mit einem externen Prozess auf genau diese Art und Weise kommunizieren, sind schlicht falsch.
Bl3nder
User
Beiträge: 139
Registriert: Freitag 3. Januar 2020, 17:07

Ok Ich danke euch :)
Eine Vision ohne Aktion bleibe eine Illusion
Bl3nder
User
Beiträge: 139
Registriert: Freitag 3. Januar 2020, 17:07

Hey Leute Ich hätte doch nochmal eine kleine Frage:

Pseudocode:

Code: Alles auswählen

import logging
import sys


def logger(meldung):
    logging.basicConfig(filename='Fehler.log', filemode='w', level=logging.DEBUG, format='%(asctime)s %(message)s')
    logging.error(meldung)


def main():
    try:
        f = open("doesnotexist")
    except FileNotFoundError:
        pfad = "doesnotexist"
        logger(f"({pfad},ist nicht vorhanden")
        ´


if __name__ == "__main__":
    main()

Auch wenn hier viele geschrieben haben das die meisten sys.exist sehr selten benötigt haben hätte erneut eine abschließende Frage zu dem Thema mal angenommen Ich lasse o.g Skript Täglich laufen ( mit dem Aufgabenplaner) ohne try und except würde die Fehlermeldung nach oben prallen und das skript mit exit code 1 beenden alles soweit ok.Ich möchte diesen Fehler nun aber loggen wie würde Ich das den alternative sonst machen wenn Ich nun nicht nach den logger nicht sys.exit(1) aufrufe ? Ich meine sonst würde von dem Skript Exit Code 0 zurückgegeben werden und der Aufgabenplaner würde denken das alles ordnungsgemäß ausgeführt wurde und würde eventuell gar nicht die Maßnahmen die beim Aufgabenplaner hinterlegt sind ausführen ( zum Beispiel probier es jedes halbe Stunde erneut ....) Würdet ihr hier also sys.exit(1) benutzen oder nicht?
Eine Vision ohne Aktion bleibe eine Illusion
Benutzeravatar
sparrow
User
Beiträge: 4144
Registriert: Freitag 17. April 2009, 10:28

Du möchtest nur loggen und ansonsten das Verhalten nicht ändern? Ein raise am Ende des except-Blocks reicht die Exception weiter.
Bl3nder
User
Beiträge: 139
Registriert: Freitag 3. Januar 2020, 17:07

Ach natürlich Ich Idiot stimmt Ich danke dir sparrow.Und ja kommt das so nicht häufig vor das man eventuell nicht alle Fehler abfangen kann dafür aber aber alles versucht zu loggen ?
Eine Vision ohne Aktion bleibe eine Illusion
Antworten