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:
- Schreiben einer Klasse mit
__enter__()
Und__exit__()
Methoden. - Verwendung der
contextlib
Modul, das diecontextmanager
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 deswith
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 dieNon-compulsory
Typ aus dem Schreibmodul für das Verbindungsobjektconn
. Wir gebrauchenNon-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 derwith
Anweisung. Es behandelt die Bereinigungsaktion beim Schließen der Verbindung. Die Parameterexc_type
,exc_value
Undtraceback
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 deryield
Anweisung stellt dann die Verbindung zum Codeblock imwith
Anweisungsblock. Beachten Sie, dassyield
selbst ist nicht immun gegen Ausnahmen, wir verpacken es in einstrive
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.