benutzerdefinierter Kontext-Managerbenutzerdefinierter Kontext-Manager
Bild vom Autor

Kontextmanager in Python ermöglichen Ihnen eine effizientere Arbeit mit Ressourcen – sie erleichtern das Ein- und Abbauen von Ressourcen, selbst wenn bei der Arbeit mit den Ressourcen Fehler auftreten. Im Tutorial zu Schreiben von effizientem Python-Codehabe ich erklärt, was Kontextmanager sind und warum sie hilfreich sind. Und in 3 interessante Verwendungsmöglichkeiten für Pythons Kontextmanagerhabe ich die Verwendung von Kontextmanagern bei der Verwaltung von Unterprozessen, Datenbankverbindungen und mehr besprochen.

In diesem Tutorial erfahren Sie, wie Sie Ihre eigenen benutzerdefinierten Kontextmanager erstellen. Wir überprüfen, wie Kontextmanager funktionieren, und sehen uns dann die verschiedenen Möglichkeiten an, wie Sie Ihre eigenen schreiben können. Lassen Sie uns beginnen.

Was sind Kontextmanager in Python?

Kontextmanager in Python sind Objekte, die die Verwaltung von Ressourcen wie Dateioperationen, Datenbankverbindungen oder Netzwerk-Sockets innerhalb eines kontrollierten Codeblocks ermöglichen. Sie stellen sicher, dass Ressourcen vor der Ausführung des Codeblocks ordnungsgemäß initialisiert und anschließend automatisch bereinigt werden, unabhängig davon, ob der Codeblock regular abgeschlossen wird oder eine Ausnahme auslöst.

Im Allgemeinen verfügen Kontextmanager in Python über die folgenden zwei speziellen Methoden: __enter__() Und __exit__(). Diese Methoden definieren das Verhalten des Kontextmanagers beim Betreten und Verlassen eines Kontexts.

Wie funktionieren Kontextmanager?

Wenn Sie mit Ressourcen in Python arbeiten, müssen Sie die Einrichtung der Ressource berücksichtigen, Fehler vorhersehen, Ausnahmebehandlung implementieren und schließlich die Ressource freigeben. Dazu verwenden Sie wahrscheinlich ein try-except-finally Blockieren Sie wie folgt:

strive: 
    # Organising the useful resource
    # Working with the useful resource
besides ErrorType:
    # Deal with exceptions
lastly:
    # Liberate the useful resource

Im Wesentlichen versuchen wir, die Ressource bereitzustellen und mit ihr zu arbeiten, mit Ausnahme von Fehlern, die während des Vorgangs auftreten können, und geben die Ressource schließlich frei. Die lastly Block wird immer ausgeführt, unabhängig davon, ob die Operation erfolgreich ist oder nicht. Aber mit Kontextmanagern und dem with Anweisung, können Sie wiederverwendbare try-except-finally Blöcke.

Sehen wir uns nun die Funktionsweise von Kontextmanagern an.

Section eingeben (__enter__() Methode):
Wenn ein with -Anweisung gefunden wird, __enter__() Methode des Kontextmanagers aufgerufen. Diese Methode ist für die Initialisierung und Einrichtung der Ressource verantwortlich, z. B. das Öffnen einer Datei, das Herstellen einer Datenbankverbindung und dergleichen. Der von zurückgegebene Wert __enter__() (sofern vorhanden) wird dem Kontextblock nach dem Schlüsselwort „as“ zur Verfügung gestellt.

Ausführen des Codeblocks:
Sobald die Ressource eingerichtet ist (nach __enter__() ausgeführt wird), wird der Codeblock, der mit dem with Anweisung ausgeführt wird. Dies ist die Operation, die Sie an der Ressource durchführen möchten.

Austrittsphase (__exit__() Methode):
Nachdem der Codeblock die Ausführung abgeschlossen hat – entweder regular oder aufgrund einer Ausnahme –, __exit__() Methode des Kontextmanagers aufgerufen wird. Die __exit__() Die Methode übernimmt Bereinigungsaufgaben, wie z. B. das Schließen der Ressourcen. Wenn innerhalb des Codeblocks eine Ausnahme auftritt, werden Informationen über die Ausnahme (Typ, Wert, Traceback) an __exit__() zur Fehlerbehandlung.

Um zusammenzufassen:

  • Kontextmanager bieten eine Möglichkeit, Ressourcen effizient zu verwalten, indem sie sicherstellen, dass Ressourcen ordnungsgemäß initialisiert und bereinigt werden.
  • Wir benutzen das with Anweisung, um einen Kontext zu definieren, in dem Ressourcen verwaltet werden.
  • Der __enter__() Methode initialisiert die Ressource und die __exit__() Die Methode bereinigt die Ressource, nachdem der Kontextblock abgeschlossen ist.

Nachdem wir nun wissen, wie Kontextmanager funktionieren, wollen wir mit dem Schreiben eines benutzerdefinierten Kontextmanagers für die Handhabung von Datenbankverbindungen fortfahren.

Erstellen benutzerdefinierter Kontextmanager in Python

Sie können Ihre eigenen Kontextmanager in Python mit einer der folgenden zwei Methoden schreiben:

  1. Schreiben einer Klasse mit __enter__() Und __exit__() Methoden.
  2. Verwendung der contextlib Modul, das die contextmanager Dekorator zum Schreiben eines Kontextmanagers mithilfe von Generatorfunktionen.

1. Schreiben einer Klasse mit den Methoden __enter__() und __exit__()

Sie können eine Klasse definieren, die die beiden speziellen Methoden implementiert: __enter__() Und __exit__() die den Aufbau und Abbau von Ressourcen steuern. Hier schreiben wir eine ConnectionManager Klasse, die eine Verbindung zu einer SQLite-Datenbank herstellt und die Datenbankverbindung schließt:

import sqlite3
from typing import Non-compulsory

# Writing a context supervisor class
class ConnectionManager:
    def __init__(self, db_name: str):
        self.db_name = db_name
        self.conn: Non-compulsory(sqlite3.Connection) = None

    def __enter__(self):
        self.conn = sqlite3.join(self.db_name)
        return self.conn

    def __exit__(self, exc_type, exc_value, traceback):
        if self.conn:
        self.conn.shut()

Lassen Sie uns analysieren, wie die ConnectionManager Werke:

  • Der __enter__() Methode wird aufgerufen, wenn die Ausführung in den Kontext des with Anweisung. Sie ist für die Einrichtung des Kontexts verantwortlich, in diesem Fall für die Verbindung mit einer Datenbank. Sie gibt die Ressource zurück, die verwaltet werden muss: die Datenbankverbindung. Beachten Sie, dass wir die Non-compulsory Typ aus dem Schreibmodul für das Verbindungsobjekt conn. Wir gebrauchen Non-compulsory Der Wert kann einer von zwei Typen sein: hier ein gültiges Verbindungsobjekt oder Keines.
  • Der __exit__() Methode: Wird aufgerufen, wenn die Ausführung den Kontext der with Anweisung. Es behandelt die Bereinigungsaktion beim Schließen der Verbindung. Die Parameter exc_type, exc_valueUnd traceback dienen zur Behandlung von Ausnahmen innerhalb des `with`-Blocks. Diese können verwendet werden, um festzustellen, ob der Kontext aufgrund einer Ausnahme verlassen wurde.

Nun verwenden wir die ConnectionManager im with Aussage. Wir machen Folgendes:

  • Versuchen Sie, eine Verbindung zur Datenbank herzustellen
  • Erstellen eines Cursors zum Ausführen von Abfragen
  • Erstellen einer Tabelle und Einfügen von Datensätzen
  • Abfragen der Datenbanktabelle und Abrufen der Abfrageergebnisse
db_name = "library.db"

# Utilizing ConnectionManager context supervisor immediately
with ConnectionManager(db_name) as conn:
	cursor = conn.cursor()

	# Create a books desk if it would not exist
	cursor.execute("""
    	CREATE TABLE IF NOT EXISTS books (
        	id INTEGER PRIMARY KEY,
        	title TEXT,
        	writer TEXT,
        	publication_year INTEGER
    	)
	""")

	# Insert pattern e book information
	books_data = (
    	("The Nice Gatsby", "F. Scott Fitzgerald", 1925),
    	("To Kill a Mockingbird", "Harper Lee", 1960),
    	("1984", "George Orwell", 1949),
    	("Delight and Prejudice", "Jane Austen", 1813)
	)
	cursor.executemany("INSERT INTO books (title, writer, publication_year) VALUES (?, ?, ?)", books_data)
	conn.commit()

	# Retrieve and print all e book information
	cursor.execute("SELECT * FROM books")
	information = cursor.fetchall()
	print("Library Catalog:")
	for file in information:
    	    book_id, title, writer, publication_year = file
    	    print(f"E book ID: {book_id}, Title: {title}, Writer: {writer}, 12 months: {publication_year}")
            cursor.shut()

Wenn Sie den obigen Code ausführen, sollte die folgende Ausgabe erscheinen:

Output >>>

Library Catalog:
E book ID: 1, Title: The Nice Gatsby, Writer: F. Scott Fitzgerald, 12 months: 1925
E book ID: 2, Title: To Kill a Mockingbird, Writer: Harper Lee, 12 months: 1960
E book ID: 3, Title: 1984, Writer: George Orwell, 12 months: 1949
E book ID: 4, Title: Delight and Prejudice, Writer: Jane Austen, 12 months: 1813

2. Verwenden des @contextmanager Decorators aus contextlib

Der contextlib Modul bietet die @contextmanager Dekorator, der verwendet werden kann, um eine Generatorfunktion als Kontextmanager zu definieren. So machen wir es für das Beispiel der Datenbankverbindung:

# Writing a generator operate with the `@contextmanager` decorator
import sqlite3
from contextlib import contextmanager

@contextmanager
def database_connection(db_name: str):
    conn = sqlite3.join(db_name)
    strive:
        yield conn  # Present the connection to the 'with' block
    lastly:
        conn.shut()  # Shut the connection upon exiting the 'with' block

So funktioniert das database_connection Funktion funktioniert:

  • Der database_connection Funktion stellt zunächst eine Verbindung her, die der yield Anweisung stellt dann die Verbindung zum Codeblock im with Anweisungsblock. Beachten Sie, dass yield selbst ist nicht immun gegen Ausnahmen, wir verpacken es in ein strive Block.
  • Der lastly Der Block stellt sicher, dass die Verbindung immer geschlossen wird, unabhängig davon, ob eine Ausnahme ausgelöst wurde oder nicht. So wird sichergestellt, dass es zu keinen Ressourcenlecks kommt.

Wie zuvor verwenden wir dies in einem with Stellungnahme:

db_name = "library.db"

# Utilizing database_connection context supervisor immediately
with database_connection(db_name) as conn:
	cursor = conn.cursor()

	# Insert a set of e book information
	more_books_data = (
    	("The Catcher within the Rye", "J.D. Salinger", 1951),
    	("To the Lighthouse", "Virginia Woolf", 1927),
    	("Dune", "Frank Herbert", 1965),
    	("Slaughterhouse-5", "Kurt Vonnegut", 1969)
	)
	cursor.executemany("INSERT INTO books (title, writer, publication_year) VALUES (?, ?, ?)", more_books_data)
	conn.commit()

	# Retrieve and print all e book information
	cursor.execute("SELECT * FROM books")
	information = cursor.fetchall()
	print("Up to date Library Catalog:")
	for file in information:
    	    book_id, title, writer, publication_year = file
    	    print(f"E book ID: {book_id}, Title: {title}, Writer: {writer}, 12 months: {publication_year}")
        cursor.shut()

Wir stellen eine Verbindung zur Datenbank her, fügen weitere Datensätze ein, fragen die Datenbank ab und holen die Ergebnisse der Abfrage. Hier ist die Ausgabe:

Output >>>

Up to date Library Catalog:
E book ID: 1, Title: The Nice Gatsby, Writer: F. Scott Fitzgerald, 12 months: 1925
E book ID: 2, Title: To Kill a Mockingbird, Writer: Harper Lee, 12 months: 1960
E book ID: 3, Title: 1984, Writer: George Orwell, 12 months: 1949
E book ID: 4, Title: Delight and Prejudice, Writer: Jane Austen, 12 months: 1813
E book ID: 5, Title: The Catcher within the Rye, Writer: J.D. Salinger, 12 months: 1951
E book ID: 6, Title: To the Lighthouse, Writer: Virginia Woolf, 12 months: 1927
E book ID: 7, Title: Dune, Writer: Frank Herbert, 12 months: 1965
E book ID: 8, Title: Slaughterhouse-5, Writer: Kurt Vonnegut, 12 months: 1969

Beachten Sie, dass wir das Cursorobjekt öffnen und schließen. Sie können das Cursorobjekt additionally auch in einer with-Anweisung verwenden. Ich schlage vor, das als kurze Übung auszuprobieren!

Einpacken

Und das battle’s. Ich hoffe, Sie haben gelernt, wie Sie Ihre eigenen benutzerdefinierten Kontextmanager erstellen. Wir haben uns zwei Ansätze angesehen: die Verwendung einer Klasse mit __enter__() Und __exit()__ Methoden und Verwendung einer Generatorfunktion, dekoriert mit dem @contextmanager Dekorateur.

Es ist leicht zu erkennen, dass die Verwendung eines Kontextmanagers folgende Vorteile mit sich bringt:

  • Der Aufbau und Abbau von Ressourcen wird automatisch verwaltet, wodurch Ressourcenlecks minimiert werden.
  • Der Code ist übersichtlicher und einfacher zu warten.
  • Sauberere Ausnahmebehandlung beim Arbeiten mit Ressourcen.

Wie immer können Sie Den Code finden Sie auf GitHub. Machen Sie weiter mit dem Programmieren!

Bala Priya C ist Entwicklerin und technische Redakteurin aus Indien. Sie arbeitet gerne an der Schnittstelle zwischen Mathematik, Programmierung, Datenwissenschaft und Inhaltserstellung. Ihre Interessens- und Fachgebiete umfassen DevOps, Datenwissenschaft und natürliche Sprachverarbeitung. Sie liest, schreibt, programmiert und trinkt gerne Kaffee! Derzeit arbeitet sie daran, ihr Wissen zu lernen und mit der Entwickler-Group zu teilen, indem sie Tutorials, Anleitungen, Meinungsbeiträge und mehr verfasst. Bala erstellt auch ansprechende Ressourcenübersichten und Programmier-Tutorials.



Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert