Python Context Manager

PythonBeginner
Jetzt üben

Einführung

Obwohl Python's Context Manager weit verbreitet sind, verstehen nur wenige den eigentlichen Zweck hinter ihrer Verwendung. Diese Anweisungen, die üblicherweise beim Lesen und Schreiben von Dateien verwendet werden, helfen der Anwendung, Systemressourcen zu schonen und das Ressourcenmanagement zu verbessern, indem sie sicherstellen, dass bestimmte Ressourcen nur für bestimmte Prozesse genutzt werden.

In diesem Lab lernen Sie, wie Sie die with-Anweisung für die automatische Ressourcenverwaltung verwenden, und erstellen anschließend Ihre eigenen Context Manager mithilfe von zwei verschiedenen Methoden: einem funktionsbasierten Ansatz und einem klassenbasierten Ansatz.

Die with-Anweisung

In diesem Schritt lernen Sie, wie Sie die with-Anweisung mit Kontextmanagern wie Datei-Objekten verwenden. Ein Kontextmanager ist ein Objekt, das benachrichtigt wird, wenn ein Kontext (ein Codeblock) beginnt und endet. Die with-Anweisung kümmert sich automatisch um diesen Benachrichtigungsprozess.

Zum Beispiel sind Datei-Objekte Kontextmanager. Wenn ein with-Block beendet wird, wird das Datei-Objekt automatisch geschlossen, selbst wenn Fehler innerhalb des Blocks auftreten. Dies verhindert Datenverlust und Ressourcenlecks.

Hinweis: Wenn Sie mit der WebIDE (ähnlich VS Code) nicht vertraut sind, lernen Sie dies zuerst in diesem Lab.

Sehen wir uns das in Aktion an. Öffnen Sie im Datei-Explorer auf der linken Seite die Datei main.py. Kopieren Sie den folgenden Code und fügen Sie ihn dort ein. Dieser Code erstellt und beschreibt zunächst eine Datei und liest dann deren Inhalt, alles unter Verwendung der with-Anweisung.

## Wir werden eine Datei erstellen, um die 'with'-Anweisung zu demonstrieren.
## Zuerst schreiben wir einige Inhalte in eine Datei.
with open('my_file.txt', 'w') as f:
    f.write('This is a test file.')

## Nun lesen wir sie mithilfe eines Kontextmanagers wieder ein.
## Die Datei wird beim Verlassen des 'with'-Blocks automatisch geschlossen.
with open('my_file.txt') as f:
    file_contents = f.read()
    print(file_contents)

## Die Datei wird hier automatisch geschlossen, selbst wenn ein Fehler aufgetreten ist.
print("\nFile has been read and closed.")

Führen Sie nun das Skript im Terminal aus, um die Ausgabe zu sehen.

python3 main.py

Sie sollten die folgende Ausgabe sehen, die bestätigt, dass erfolgreich in die Datei geschrieben und aus ihr gelesen wurde. Die with-Anweisung stellt sicher, dass my_file.txt nach den Schreib- und Leseoperationen ordnungsgemäß geschlossen wird.

This is a test file.

File has been read and closed.

Die Verwendung einer with-Anweisung ist die empfohlene Methode zur Verwaltung von Ressourcen wie Dateien oder Netzwerkverbindungen, da sie Ihren Code sauberer und sicherer macht.

Einen eigenen Context Manager schreiben

In diesem Schritt erfahren Sie, wie Sie einen benutzerdefinierten Context Manager mithilfe einer Generatorfunktion und des Decorators @contextlib.contextmanager erstellen. Dies ist eine prägnante Methode zur Erstellung einfacher Context Manager.

Der Code vor der yield-Anweisung wird ausgeführt, wenn der with-Block betreten wird (die Setup-Logik), und der Code nach der yield-Anweisung wird ausgeführt, wenn er verlassen wird (die Cleanup-Logik). Der Wert, der yielded wird, kann mithilfe des as-Schlüsselworts in der with-Anweisung einer Variablen zugewiesen werden.

Öffnen Sie die Datei function_cm.py im Dateiexplorer. Kopieren Sie den folgenden Code in die Datei.

## Function-based context manager using contextlib decorator
import contextlib

@contextlib.contextmanager
def context_manager(num):
    print('Enter')  ## Code before yield runs on __enter__
    yield num + 1   ## Value yielded becomes 'cm' variable
    print('Exit')    ## Code after yield runs on __exit__

with context_manager(2) as cm:  ## cm receives the yielded value (3)
    print('Right in the middle with cm = {}'.format(cm))

Führen Sie nun das Skript im Terminal aus.

python3 function_cm.py

Sie werden die folgende Ausgabe sehen. Beachten Sie die Reihenfolge der Ausführung: Der Code vor yield wird zuerst ausgeführt, dann der Code innerhalb des with-Blocks und schließlich der Code nach yield.

Enter
Right in the middle with cm = 3
Exit

Dieser Ansatz ist sehr nützlich für die Erstellung temporärer Kontexte, wie z. B. das Einrichten und Aufräumen einer Datenbankverbindung oder das vorübergehende Ändern einer Einstellung.

Klassenbasierter Context Manager

In diesem Schritt implementieren Sie einen Context Manager als Klasse. Dieser Ansatz bietet mehr Kontrolle und eignet sich für komplexere Szenarien. Um einen klassenbasierten Context Manager zu erstellen, müssen Sie zwei spezielle Methoden definieren: __enter__ und __exit__.

  • __enter__: Diese Methode wird aufgerufen, wenn die with-Anweisung betreten wird. Sie sollte die Setup-Logik ausführen. Ihr Rückgabewert wird der Variablen nach as zugewiesen, falls diese angegeben ist.
  • __exit__: Diese Methode wird aufgerufen, wenn der with-Block verlassen wird, entweder regulär oder aufgrund einer Ausnahme (Exception). Sie sollte die Cleanup-Logik ausführen.

Erstellen wir einen solchen Manager. Öffnen Sie die Datei class_cm.py und kopieren Sie den folgenden Code hinein.

## Class-based context manager: implement __enter__ and __exit__ methods
class ContextManager:
    def __enter__(self, *args, **kwargs):  ## Called when entering 'with' block
        print("--enter--")
        return self  ## Can return object to use as 'as' variable

    def __exit__(self, *args):  ## Called when exiting 'with' block
        print("--exit--")

with ContextManager():  ## Calls __enter__, then __exit__ when done
    print("test")

Führen Sie das Skript im Terminal aus.

python3 class_cm.py

Die Ausgabe demonstriert den Kontrollfluss. Die Methode __enter__ wird zuerst aufgerufen, gefolgt vom Code innerhalb des with-Blocks, und schließlich wird die Methode __exit__ für das Aufräumen aufgerufen.

--enter--
test
--exit--

Der klassenbasierte Ansatz ist mächtig, da er es Ihnen ermöglicht, komplexe Setup- und Teardown-Logik in einem einzigen, wiederverwendbaren Objekt zu kapseln.

Zusammenfassung

Herzlichen Glückwunsch zum Abschluss des Labs! Sie haben gelernt, wie man Ressourcen in Python mithilfe von Context Managern effektiv verwaltet.

Sie begannen mit der gängigen with-Anweisung für die sichere Dateiverwaltung. Anschließend haben Sie gelernt, wie Sie Ihre eigenen benutzerdefinierten Context Manager mit zwei verschiedenen Methoden erstellen:

  • Ein funktionsbasierter Ansatz mit dem Decorator @contextlib.contextmanager, der sich hervorragend für einfache Setup- und Teardown-Aufgaben eignet.
  • Ein klassenbasierter Ansatz durch die Implementierung der Methoden __enter__ und __exit__, der sich ideal für komplexere Ressourcenverwaltung eignet.

Diese Fähigkeiten sind entscheidend für das Schreiben von sauberem, zuverlässigem und effizientem Python-Code, der Ressourcen ordnungsgemäß behandelt.