Ich bin with
heute zum ersten Mal auf die Python- Anweisung gestoßen. Ich benutze Python seit einigen Monaten leicht und wusste nicht einmal von seiner Existenz! Angesichts seines etwas dunklen Status dachte ich, es lohnt sich zu fragen:
- Wofür soll die Python-
with
Anweisung verwendet werden? - Wofür verwendest du es?
- Gibt es Fallstricke, die ich beachten muss, oder allgemeine Anti-Muster, die mit ihrer Verwendung verbunden sind? Gibt es Fälle, in denen es besser ist
try..finally
alswith
? - Warum wird es nicht weiter verbreitet?
- Welche Standardbibliotheksklassen sind damit kompatibel?
with
in der Python 3-Dokumentation.Antworten:
Ich glaube, dies wurde bereits von anderen Benutzern vor mir beantwortet, daher füge ich es der Vollständigkeit halber hinzu: Die
with
Anweisung vereinfacht die Ausnahmebehandlung, indem sie allgemeine Vorbereitungs- und Bereinigungsaufgaben in sogenannten Kontextmanagern kapselt . Weitere Details finden Sie in PEP 343 . Beispielsweise ist dieopen
Anweisung ein eigenständiger Kontextmanager, mit dem Sie eine Datei öffnen, geöffnet lassen können, solange sich die Ausführung im Kontext derwith
Anweisung befindet, in der Sie sie verwendet haben, und sie schließen können, sobald Sie den Kontext verlassen. egal ob Sie es aufgrund einer Ausnahme oder während des regulären Kontrollflusses verlassen haben. Diewith
Anweisung kann daher auf ähnliche Weise wie das RAII-Muster in C ++ verwendet werden: Einige Ressourcen werden von derwith
Anweisung und freigegeben, wenn Sie denwith
Kontext verlassen .Einige Beispiele sind: Öffnen von Dateien mit
with open(filename) as fp:
, Erfassen von Sperren mitwith lock:
(wolock
ist eine Instanz vonthreading.Lock
). Sie können auch Ihre eigenen Kontextmanager mit demcontextmanager
Dekorator von erstellencontextlib
. Zum Beispiel benutze ich dies oft, wenn ich das aktuelle Verzeichnis vorübergehend ändern und dann dorthin zurückkehren muss, wo ich war:Hier ist ein weiteres Beispiel , das vorübergehend umleitet
sys.stdin
,sys.stdout
undsys.stderr
zu einem anderen Datei - Handle und stellt sie wieder her später:Und schließlich ein weiteres Beispiel, das einen temporären Ordner erstellt und beim Verlassen des Kontexts bereinigt:
quelle
with
Anweisung eine Variable mit Daten füllen soll, bis die Anweisungen darunter vollständig sind, und dann die Variable freigeben?with open('myScript.py', 'r') as f: pass
. Ich hatte erwartet, die Variable aufrufen zu können, um denf
Textinhalt des Dokuments anzuzeigen, da dies der Fall wäre, wenn das Dokumentf
über eine reguläreopen
Anweisung zugewiesen würde :f = open('myScript.py').read()
. Aber stattdessen habe ich folgendes bekommen :<_io.TextIOWrapper name='myScript.py' mode='r' encoding='cp1252'>
. Was bedeutet das?with
wird die Notwendigkeit fürread
die eigentliche Datei nicht beseitigt . Bei denwith
Anrufenopen
- es weiß nicht, was Sie damit tun müssen - möchten Sie beispielsweise eine Suche durchführen.with
Anweisung kann eine Variable mit Daten füllen oder andere Änderungen an der Umgebung vornehmen, bis die Anweisungen darunter vollständig sind, und dann jede Art von Bereinigung durchführen, die erforderlich ist. Die Arten der Bereinigung, die durchgeführt werden können, sind beispielsweise das Schließen einer geöffneten Datei oder wie bei @Tamas in diesem Beispiel das Ändern der Verzeichnisse auf den vorherigen Stand usw. Da Python über eine Speicherbereinigung verfügt, ist das Freigeben einer Variablen nicht wichtig Anwendungsfall.with
wird im Allgemeinen für andere Arten der Bereinigung verwendet.Ich würde zwei interessante Vorträge vorschlagen:
1. Die
with
Anweisung wird verwendet, um die Ausführung eines Blocks mit Methoden zu versehen, die von einem Kontextmanager definiert wurden. Auf diese Weise können allgemeinetry...except...finally
Verwendungsmuster für eine bequeme Wiederverwendung gekapselt werden.2. Sie könnten so etwas tun wie:
ODER
ODER (Python 3.1)
ODER
3. Ich sehe hier kein Antipattern. Dive in Python
zitieren :
4. Ich denke, es hängt mit der Gewohnheit der Programmierer zusammen,
try..catch..finally
Aussagen aus anderen Sprachen zu verwenden.quelle
with
.Die Python-
with
Anweisung ist eine integrierte Sprachunterstützung für dieResource Acquisition Is Initialization
in C ++ häufig verwendete Sprache . Es soll die sichere Erfassung und Freigabe von Betriebssystemressourcen ermöglichen.Die
with
Anweisung erstellt Ressourcen innerhalb eines Bereichs / Blocks. Sie schreiben Ihren Code mit den Ressourcen innerhalb des Blocks. Wenn der Block beendet wird, werden die Ressourcen unabhängig vom Ergebnis des Codes im Block sauber freigegeben (dh ob der Block normal beendet wird oder aufgrund einer Ausnahme).Viele Ressourcen in der Python-Bibliothek, die dem von der
with
Anweisung geforderten Protokoll entsprechen und daher sofort verwendet werden können. Jeder kann jedoch Ressourcen erstellen, die in einer with-Anweisung verwendet werden können, indem das gut dokumentierte Protokoll implementiert wird: PEP 0343Verwenden Sie es immer dann, wenn Sie Ressourcen in Ihrer Anwendung erwerben, auf die explizit verzichtet werden muss, z. B. Dateien, Netzwerkverbindungen, Sperren und dergleichen.
quelle
Der Vollständigkeit halber werde ich noch einmal meinen nützlichsten Anwendungsfall für
with
Aussagen hinzufügen .Ich mache viel wissenschaftliches Rechnen und für einige Aktivitäten brauche ich die
Decimal
Bibliothek für willkürliche Präzisionsberechnungen. Ein Teil meines Codes benötigt hohe Präzision und für die meisten anderen Teile weniger Präzision.Ich setze meine Standardgenauigkeit auf eine niedrige Zahl und verwende dann
with
, um für einige Abschnitte eine genauere Antwort zu erhalten:Ich verwende dies häufig beim hypergeometrischen Test, bei dem große Zahlen in Form von Fakultäten unterteilt werden müssen. Wenn Sie genomische Skalenberechnungen durchführen, müssen Sie auf Rundungs- und Überlauffehler achten.
quelle
Ein Beispiel für ein Antimuster könnte darin bestehen, das
with
Innere einer Schleife zu verwenden, wenn es effizienter wäre, daswith
Äußere der Schleife zu habenzum Beispiel
vs.
Der erste Weg ist das Öffnen und Schließen der Datei für jeden,
row
was zu Leistungsproblemen führen kann, im Vergleich zum zweiten Weg, bei dem die Datei nur einmal geöffnet und geschlossen wird.quelle
Siehe PEP 343 - Die 'with'-Anweisung , am Ende befindet sich ein Beispielabschnitt.
quelle
Die Punkte 1, 2 und 3 sind hinreichend gut abgedeckt:
4: Es ist relativ neu und nur in Python2.6 + (oder Python2.5 mit
from __future__ import with_statement
) verfügbar.quelle
Die with-Anweisung funktioniert mit sogenannten Kontextmanagern:
http://docs.python.org/release/2.5.2/lib/typecontextmanager.html
Die Idee ist, die Ausnahmebehandlung zu vereinfachen, indem die erforderliche Bereinigung durchgeführt wird, nachdem der Block 'with' verlassen wurde. Einige der in Python integrierten Funktionen arbeiten bereits als Kontextmanager.
quelle
Ein weiteres Beispiel für die sofort einsatzbereite Unterstützung, das zunächst etwas verwirrend sein kann, wenn Sie an das Verhalten von integrierten Geräten gewöhnt sind
open()
, sindconnection
Objekte beliebter Datenbankmodule wie:Die
connection
Objekte sind Kontextmanager und können als solche sofort in einem verwendet werden.with-statement
Beachten Sie jedoch Folgendes:Dies bedeutet, dass der Programmierer darauf achten muss, die Verbindung selbst zu schließen, aber es ermöglicht, eine Verbindung herzustellen und in mehreren zu verwenden
with-statements
, wie in den psycopg2-Dokumenten gezeigt :Im obigen Beispiel werden Sie feststellen, dass die
cursor
Objekte vonpsycopg2
auch Kontextmanager sind. Aus der entsprechenden Dokumentation zum Verhalten:quelle
In Python wird die Anweisung " with " im Allgemeinen verwendet, um eine Datei zu öffnen, die in der Datei vorhandenen Daten zu verarbeiten und die Datei zu schließen, ohne eine close () -Methode aufzurufen. Die Anweisung "with" vereinfacht die Ausnahmebehandlung, indem Bereinigungsaktivitäten bereitgestellt werden.
Allgemeine Form von mit:
Hinweis: Sie müssen die Datei nicht schließen, indem Sie close () bei file-var.close () aufrufen.
quelle