CodeGym /Java Kurs /Python SELF DE /Der with-Operator

Der with-Operator

Python SELF DE
Level 21 , Lektion 3
Verfügbar

4.1 Schließen einer Datei und Fehlerbehandlung

Manchmal treten beim Lesen einer Datei Fehler oder Ausnahmen auf, und die Datei bleibt ungeschlossen. Dies kann potenziell zu einem Speicherleck oder einem Leck von file handler führen. Daher sollte die Arbeit mit einer Datei in einen try-except-Block eingebettet werden.

Angenommen, du hattest folgenden Code:


file = open('example.txt', 'a') # Datei öffnen
file.write("This is a new line added to the file.")
file.close()  # Datei schließen

Er muss in einen try-except-Block eingebettet werden:


try:
    file = open('example.txt', 'a')  # Datei öffnen
    file.write("This is a new line added to the file.")
    file.close()  # Datei schließen
except FileNotFoundError:
    print("File not found")
    file.close()  # Datei schließen

Um die Methode close() nicht zweimal schreiben zu müssen, kann sie in einen finally-Block verschoben werden:


try:
    file = open('example.txt', 'a')  # Datei öffnen
    file.write("This is a new line added to the file.")
except FileNotFoundError:
    print("File not found")
finally:
    file.close()  # Datei schließen

Dieser Code sieht gut aus, aber… funktioniert nicht, da die Variable file nur im try-Block definiert ist und in den Blöcken except und finally nicht verfügbar ist.

Deshalb müssen wir die Variable eine Ebene höher definieren:


file = None
try:
    file = open('example.txt', 'a')  # Datei öffnen
    file.write("This is a new line added to the file.")
except FileNotFoundError:
    print("File not found")
finally:
    file.close()  # Datei schließen

Diese Lösung ist besser, hat aber auch Nachteile. Zum Beispiel, wenn die Datei nicht geöffnet wird, bleibt in der Variablen file None. Dann wird der Versuch, die Datei zu schließen, einen Fehler verursachen — es wird versucht, auf die Methode close() eines nicht existierenden Objekts zuzugreifen.

Deshalb müssen wir eine Überprüfung vor dem Aufruf der Methode close() hinzufügen:


file = None
try:
    file = open('example.txt', 'a')  # Datei öffnen
    file.write("This is a new line added to the file.")
except FileNotFoundError:
    print("File not found")
finally:
    if file:
        file.close()  # Datei schließen

Wenn du überrascht bist, dass aus 3 Zeilen Code 9 geworden sind, bist du nicht allein. Glücklicherweise gibt es bereits eine Lösung für dieses Problem, über die wir als Nächstes sprechen werden.

4.2 Der with-Operator

Der with-Operator in Python bietet eine bequeme Methode zur Verwaltung von Ressourcen, wie Dateien, und gewährleistet deren automatisches Schließen nach Abschluss des with-Blocks. Dies vereinfacht den Code und verhindert Ressourcenlecks, wie ungeschlossene Dateien.

Allgemeine Syntax des with-Operators:


with expression as variable:
    Arbeite mit der Variablen

Der with-Operator wird verwendet, um die Ausführung eines Codeblocks mit einem Kontextmanager zu umschließen. Bei Verwendung des with-Operators ruft Python automatisch die Methoden __enter__() und __exit__() des Kontextmanager-Objekts auf, was die Ressourcenverwaltung vereinfacht.

Beispiel für die Verwendung von with zur Arbeit mit Dateien:


with open('example.txt', 'w') as file:
    file.write("Hello, World!\n")
    file.write("This is a test file.\n")

In diesem Beispiel wird die Datei example.txt im Schreibmodus geöffnet, und der Dateiname wird der Variablen file zugewiesen. Der Codeblock innerhalb von with schließt die Datei automatisch nach Abschluss aller Schreibvorgänge.

4.3 Automatisches Schließen einer Datei

Eines der Hauptvorteile der Verwendung des with-Operators ist das automatische Schließen der Datei nach Abschluss des Codeblocks. Dies geschieht sogar im Falle einer Ausnahme, was den Code sicherer und zuverlässiger macht.

Beispiel für das automatische Schließen einer Datei:


try:
    with open('example.txt', 'w') as file:
        file.write("Hello, World!\n")
        file.write("This is a test file.\n")
        # Ausnahme auslösen, um zu überprüfen, ob die Datei dennoch geschlossen wird
        raise Exception("Something went wrong")
except Exception as e:
    print(f"Caught an exception: {e}")
# An dieser Stelle ist die Datei bereits geschlossen

Verwende immer den with-Operator bei der Arbeit mit Dateien. Es ist einfach und verhindert viele Fehler.

4.4 Unter der Haube des with-Operators

Die Grundlage für die Funktionsweise des with-Operators sind die Methoden __enter__() und __exit__(), die in der Klasse implementiert sein müssen, die als Kontextmanager verwendet wird.

Damit ein Objekt mit dem with-Operator verwendet werden kann, muss es die Methoden __enter__() und __exit__() implementieren. Diese Methoden definieren das Verhalten beim Ein- und Austritt aus dem Kontext.

Methode __enter__()

Die Methode __enter__() wird beim Betreten des with-Blocks aufgerufen. Sie führt die Initialisierung der Ressource durch und gibt das Objekt zurück, das an die nach as angegebene Variable gebunden wird.

Methode __exit__()

Die Methode __exit__() wird beim Verlassen des with-Blocks aufgerufen. Sie führt abschließende Aktionen durch, wie die Freigabe von Ressourcen oder das Schließen von Dateien. Die Methode nimmt drei Argumente entgegen: exc_type, exc_val und exc_tb, die Informationen über die Ausnahme enthalten, falls eine aufgetreten ist.

  • exc_type: Typ der Ausnahme (z.B. ZeroDivisionError).
  • exc_val: Wert der Ausnahme (z.B. Fehlermeldung).
  • exc_tb: Stack-Trace der Ausnahme.

Wenn die Methode __exit__() True zurückgibt, wird die Ausnahme unterdrückt. Wenn sie False zurückgibt, wird die Ausnahme erneut ausgelöst.

Beispiel:


class MyContextManager:
    def __enter__(self):
        print("Entering the context")
        return self
        
    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type:
            print(f"An exception occurred: {exc_type}, {exc_val}")
        return False  # Ausnahme wird nicht unterdrückt
        
with MyContextManager() as manager:
    print("Inside the with block")
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION