Ich habe das in jemandes Code gesehen. Was bedeutet das?
def __enter__(self):
return self
def __exit__(self, type, value, tb):
self.stream.close()
from __future__ import with_statement#for python2.5
class a(object):
def __enter__(self):
print 'sss'
return 'sss111'
def __exit__(self ,type, value, traceback):
print 'ok'
return False
with a() as s:
print s
print s
python
oop
with-statement
zjm1126
quelle
quelle
Antworten:
Mit diesen magischen Methoden (
__enter__
,__exit__
) können Sie Objekte implementieren, die einfach mit derwith
Anweisung verwendet werden können .Die Idee ist, dass es einfach ist, Code zu erstellen, für den ein Bereinigungscode ausgeführt werden muss (stellen Sie sich diesen als
try-finally
Block vor). Noch eine Erklärung hier .Ein nützliches Beispiel könnte ein Datenbankverbindungsobjekt sein (das die Verbindung dann automatisch schließt, sobald die entsprechende 'with'-Anweisung den Gültigkeitsbereich verlässt):
Verwenden Sie dieses Objekt wie oben erläutert mit der
with
Anweisung (möglicherweise müssen Sie diesfrom __future__ import with_statement
oben in der Datei tun, wenn Sie Python 2.5 verwenden).PEP343 - Die 'with'-Anweisung' hat auch eine schöne Beschreibung.
quelle
__enter__
sollte zurückkehrenself
immer dann nur andere Methoden der Klasse kann auf den Kontext aufgerufen werden.def __enter__(self)
in PEP 343 und niemand tut diesreturn self
: python.org/dev/peps/pep-0343 . Warum denkst du das?self
Objekte aufrufen, wie hier erläutert: stackoverflow.com/questions/38281853/… 2) self.XYZ ist nur ein Teil von self object und Die Rückgabe des Griffs nur auf genau das scheint mir aus Sicht der Wartung unangemessen. Ich würde es vorziehen, das Handle zurückzugeben, um das Objekt zu vervollständigen, und dann öffentliche APIs nur für das Komponentenobjekt bereitzustellenself
, das ich dem Benutzer wie inwith open(abc.txt, 'r') as fin: content = fin.read()
self
von zurück__enter__
, weshalb Sie die Datei wief
innen verarbeiten könnenwith open(...) as f
Wenn Sie wissen, was Kontextmanager sind, brauchen Sie nichts mehr zu verstehen
__enter__
und__exit__
magische Methoden. Sehen wir uns ein sehr einfaches Beispiel an.In diesem Beispiel öffne ich myfile.txt mit Hilfe der Open- Funktion. Der try / finally- Block stellt sicher, dass myfile.txt auch dann geschlossen wird, wenn eine unerwartete Ausnahme auftritt .
Jetzt öffne ich die gleiche Datei mit der folgenden Anweisung:
Wenn Sie sich den Code ansehen, habe ich die Datei nicht geschlossen und es gibt keinen try / finally- Block. Denn mit Anweisung wird myfile.txt automatisch geschlossen . Sie können es sogar überprüfen, indem Sie das
print(fp.closed)
Attribut aufrufen , das zurückgibtTrue
.Dies liegt daran, dass die von der Funktion open zurückgegebenen Dateiobjekte (in meinem Beispiel fp) über zwei integrierte Methoden
__enter__
und verfügen__exit__
. Es wird auch als Kontextmanager bezeichnet.__enter__
Die Methode wird am Anfang von mit Block__exit__
aufgerufen und die Methode wird am Ende aufgerufen. Hinweis: with- Anweisung funktioniert nur mit Objekten, die das Kontext-Mamangement-Protokoll unterstützen, dh sie haben__enter__
und__exit__
Methoden. Eine Klasse, die beide Methoden implementiert, wird als Kontextmanagerklasse bezeichnet.Definieren wir nun unsere eigene Kontextmanager- Klasse.
Ich hoffe, Sie haben jetzt ein grundlegendes Verständnis für beide
__enter__
und__exit__
magische Methoden.quelle
Ich fand es seltsam schwierig, die Python-Dokumente
__enter__
und__exit__
-Methoden von Googling zu finden. Um anderen hier zu helfen, ist der Link:https://docs.python.org/2/reference/datamodel.html#with-statement-context-managers
https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers
(Detail ist für beide Versionen gleich)
Ich hatte auf eine klare Beschreibung der
__exit__
Methodenargumente gehofft . Dies fehlt, aber wir können sie ableiten ...Vermutlich
exc_type
ist die Klasse der Ausnahme.Es heißt, Sie sollten die übergebene Ausnahme nicht erneut auslösen. Dies legt uns nahe, dass eines der Argumente eine tatsächliche Ausnahmeinstanz sein könnte ... oder Sie sollten es selbst anhand des Typs und des Werts instanziieren?
Wir können antworten, indem wir uns diesen Artikel ansehen :
http://effbot.org/zone/python-with-statement.htm
... so klar
value
ist eine Exception-Instanz.Und vermutlich
traceback
handelt es sich um ein Python- Traceback- Objekt.quelle
Zusätzlich zu den obigen Antworten zur Veranschaulichung der Aufrufreihenfolge ein einfaches Ausführungsbeispiel
Erzeugt die Ausgabe:
Zur Erinnerung: Bei Verwendung der Syntax
with myclass() as mc
erhält die Variable mc__enter__()
im obigen Fall den von zurückgegebenen WertNone
! Für eine solche Verwendung muss der Rückgabewert definiert werden, z.quelle
versuche meine Antworten hinzuzufügen (mein Gedanke an Lernen):
__enter__
und[__exit__]
beide sind Methoden, die beim Ein- und Aussteigen aus dem Hauptteil der " with-Anweisung " ( PEP 343 ) aufgerufen werden, und die Implementierung von beiden wird als Kontextmanager bezeichnet.Die with-Anweisung soll die Flusskontrolle der try finally-Klausel verbergen und den Code unergründlich machen.
Die Syntax der with-Anweisung lautet:
die übersetzt werden (wie in PEP 343 erwähnt):
Versuchen Sie einen Code:
und versuchen Sie es jetzt manuell (folgende Übersetzungssyntax):
das Ergebnis der Serverseite wie zuvor
Entschuldigung für mein schlechtes Englisch und meine unklaren Erklärungen, danke ....
quelle
Dies wird als Kontextmanager bezeichnet, und ich möchte nur hinzufügen, dass ähnliche Ansätze für andere Programmiersprachen existieren. Ein Vergleich kann hilfreich sein, um den Kontextmanager in Python zu verstehen. Grundsätzlich wird ein Kontextmanager verwendet, wenn es sich um einige Ressourcen (Datei, Netzwerk, Datenbank) handelt, die initialisiert und irgendwann heruntergefahren (entsorgt) werden müssen. In Java 7 und höher haben wir eine automatische Ressourcenverwaltung in Form von:
Beachten Sie, dass die Sitzung eine
AutoClosable
oder mehrere ihrer (vielen) Unterschnittstellen implementieren muss.In C # verwenden wir Anweisungen zum Verwalten von Ressourcen in Form von:
In dem
Session
sollte implementierenIDisposable
.In Python sollte die von uns verwendete Klasse
__enter__
und implementieren__exit__
. Es hat also die Form:Und wie andere betonten, können Sie die try / finally-Anweisung immer in allen Sprachen verwenden, um denselben Mechanismus zu implementieren. Dies ist nur syntaktischer Zucker.
quelle