Articles

GeeksforGeeks

Verwalten von Ressourcen : In jeder Programmiersprache ist die Verwendung von Ressourcen wie Dateioperationen oder Datenbankverbindungen sehr verbreitet. Diese Ressourcen sind jedoch begrenzt. Daher liegt das Hauptproblem darin, sicherzustellen, dass diese Ressourcen nach der Verwendung freigegeben werden. Wenn sie nicht freigegeben werden, führt dies zu Ressourcenlecks und kann dazu führen, dass das System entweder langsamer wird oder abstürzt. Es wäre sehr hilfreich, wenn der Benutzer einen Mechanismus zum automatischen Einrichten und Abbauen von Ressourcen hätte.In Python kann dies durch die Verwendung von Kontextmanagern erreicht werden, die den ordnungsgemäßen Umgang mit Ressourcen erleichtern. Die gebräuchlichste Methode zum Ausführen von Dateioperationen ist die Verwendung des Schlüsselworts with wie unten gezeigt:

with open("test.txt") as f:
data =f.read()



Let’s take the example of file Management. Wenn eine Datei geöffnet wird, wird ein Dateideskriptor verbraucht, der eine begrenzte Ressource darstellt. Es kann jeweils nur eine bestimmte Anzahl von Dateien von einem Prozess geöffnet werden. Das folgende Programm demonstriert es.

file_descriptors =
forx inrange(100000):
file_descriptors.append(open('test.txt', 'w'))



Ausgabe:

Traceback (most recent call last): File "context.py", line 3, in OSError: Too many open files: 'test.txt'

Eine Fehlermeldung, dass zu viele Dateien geöffnet sind. Das obige Beispiel ist ein Fall von Dateideskriptorleckage. Dies geschieht, weil zu viele Dateien geöffnet und nicht geschlossen sind. Es kann vorkommen, dass ein Programmierer vergisst, eine geöffnete Datei zu schließen.

Ressourcen mit dem Kontext-Manager verwalten :Angenommen, ein Codeblock löst eine Ausnahme aus, oder wenn er einen komplexen Algorithmus mit mehreren Rückgabepfaden hat, wird es umständlich, eine Datei an allen Stellen zu schließen.
Im Allgemeinen in anderen Sprachen bei der Arbeit mit Dateien try-except-finally wird verwendet, um sicherzustellen, dass die Datei-Ressource nach der Verwendung geschlossen wird, auch wenn es eine Ausnahme gibt.Python bietet eine einfache Möglichkeit, Ressourcen zu verwalten: Kontextmanager. Das Schlüsselwort with wird verwendet. Wenn es ausgewertet wird, sollte es zu einem Objekt führen, das die Kontextverwaltung ausführt. Kontextmanager können mit Klassen oder Funktionen (mit Dekoratoren) geschrieben werden.

Erstellen eines Kontextmanagers :

Beim Erstellen von Kontextmanagern mit Klassen muss der Benutzer sicherstellen, dass die Klasse über die folgenden Methoden verfügt: __enter__() und __exit__(). Das __enter__() gibt die Ressource zurück, die verwaltet werden muss, und das __exit__() gibt nichts zurück, sondern führt die Bereinigungsvorgänge aus.
Lassen Sie uns zunächst eine einfache Klasse namens ContextManager erstellen, um die grundlegende Struktur der Erstellung von Kontextmanagern mithilfe von Klassen zu verstehen, wie unten gezeigt:

classContextManager():
def__init__(self):
print('init method called')
def__enter__(self):
print('enter method called')
returnself
def__exit__(self, exc_type, exc_value, exc_traceback):
print('exit method called')
with ContextManager() as manager:
print('with statement block')



Output:

init method calledenter method calledwith statement blockexit method called

In diesem Fall wird ein ContextManager Objekt erstellt. Dies wird der Variablen nach dem Schlüsselwort as zugewiesen, dh manager. Beim Ausführen des obigen Programms wird nacheinander Folgendes ausgeführt:

  • __init__()
  • __enter__()
  • Anweisungstext (Code innerhalb des with-Blocks)
  • __exit__()

Dateiverwaltung mit dem Kontextmanager :

Wenden wir das obige Konzept an so erstellen Sie eine Klasse, die bei der Dateiressourcenverwaltung hilft.Die FileManager-Klasse hilft beim Öffnen einer Datei, beim Schreiben / Lesen von Inhalten und beim Schließen.

classFileManager():
def__init__(self, filename, mode):
self.filename =filename
self.mode =mode
self.file=None
def__enter__(self):
self.file=open(self.filename, self.mode)
returnself.file
def__exit__(self, exc_type, exc_value, exc_traceback):
self.file.close()
with FileManager('test.txt', 'w') as f:
f.write('Test')
print(f.closed)



Ausgabe:

True

Dateiverwaltung mit Kontextmanager und with-Anweisung :

Beim Ausführen des with-Blocks werden nacheinander die folgenden Vorgänge ausgeführt:

  • Mit test wird ein FileManager-Objekt erstellt.txt als Dateiname und w(write) als Modus, wenn die Methode __init__ ausgeführt wird.
  • Die Methode __enter__ öffnet den Test.txt-Datei im Schreibmodus (Setup-Vorgang) und gibt das FileManager-Objekt an die Variable f zurück.
  • Der Text ‚Test‘ wird in die Datei geschrieben.
  • Die Methode __exit__ sorgt dafür, dass die Datei beim Verlassen des with-Blocks geschlossen wird(Teardown-Vorgang).
    Wenn print(f.closed) ausgeführt wird, ist die Ausgabe True, da der FileManager sich bereits darum gekümmert hat, die Datei zu schließen, die sonst explizit ausgeführt werden musste.

Datenbankverbindungsverwaltung mit dem Kontextmanager :

Lassen Sie uns ein einfaches Datenbankverbindungsverwaltungssystem erstellen. Die Anzahl der Datenbankverbindungen, die gleichzeitig geöffnet werden können, ist ebenfalls begrenzt (genau wie Dateideskriptoren). Daher sind Kontextmanager hilfreich bei der Verwaltung von Verbindungen zur Datenbank, da der Programmierer möglicherweise vergisst, die Verbindung zu schließen.

frompymongo importMongoClient
classMongoDBConnectionManager():
def__init__(self, hostname, port):
self.hostname =hostname
self.port =port
self.connection =None
def__enter__(self):
self.connection =MongoClient(self.hostname, self.port)
returnself
def__exit__(self, exc_type, exc_value, exc_traceback):
self.connection.close()
with MongoDBConnectionManager('localhost', '27017') as mongo:
collection =mongo.connection.SampleDb.test
data =collection.find({'_id': 1})
print(data.get('name'))



Datenbankverbindungsverwaltung mit Kontextmanager und with-Anweisung:

Beim Ausführen des with-Blocks werden die folgenden Vorgänge nacheinander ausgeführt:

  • Ein MongoDBConnectionManager-Objekt wird mit localhost als der Hostname und 27017 als Port, wenn die Methode __init__ ausgeführt wird.
  • Die Methode __enter__ öffnet die Mongodb-Verbindung und gibt das MongoDBConnectionManager-Objekt an die Variable mongo zurück.
  • Auf die Testsammlung in der SampleDb-Datenbank wird zugegriffen und das Dokument mit _id=1 abgerufen. Das Feld Name des Dokuments wird gedruckt.
  • Die Methode __exit__ sorgt dafür, dass die Verbindung beim Verlassen des with-Blocks geschlossen wird(Teardown-Vorgang).
Artikel-Tags :