python 'with' - Anweisung, sollte ich contextlib.schließen?
from contextlib import closing
def init_db():
with closing(connect_db()) as db:
with app.open_resource('schema.sql') as f:
db.cursor().executescript(f.read())
db.commit()
Dies ist von flask tutorial Schritt 3(http://flask.pocoo.org/docs/tutorial/dbinit/#tutorial-dbinit). Und ich bin wenig neugierig auf die Linie 4, die.
Muss ich importieren und nutzen, dass " contextlib.schließen ()' - Methode?
Wenn ich gelernt habe über mit Aussage, viele Artikel sagte, es schließt sich die Datei automatisch nach dem Prozess wie folgt Aussehen.(dasselbe wie Endlich: Ding.close())
with open('filename','w') as f:
f.write(someString);
Obwohl ich nicht verwenden, die contextlib.schließen (), wie unten, Was ist Unterschied?
Es ist von version 2.7.6, Danke.
def init_db():
with connect_db() as db:
with app.open_resource('schema.sql') as f:
db.cursor().executescript(f.read())
db.commit()
- Hat das Letzte snippet zu arbeiten?
- ja..., Die funktionieren auf einmal. aber sicher nicht über furthur problem.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja, Sie sollten mit
context.closing()
; Ihre eigene version tut etwas anderes ganz.Den
with
- Anweisung können Sie einen context-manager wissen, wenn ein code-block wird betreten und verlassen; an der Ausfahrt der context-manager ist auch der Zugriff auf die Ausnahme, wenn einer aufgetreten ist. Datei-Objekte diese nutzen, um automatisch schließen Sie die Datei, wenn der block verlassen wird.Den
connect_db()
Funktion aus dem tutorial gibt einesqlit3
connection-Objekt, die man durchaus als eine Kontext-manager. Jedoch, dieconnection.__exit__()
Methode nicht schließt die Verbindung, es die Transaktion ein commit ausgeführt auf einen erfolgreichen Abschluss, oder bricht es, wenn es eine Ausnahme.Den
contextlib.closing()
Kontext-manager auf der anderen Seite, ruft dieconnection.close()
Methode für die Verbindung. Das ist etwas ganz andere.So, das zweite snippet kann funktionieren, aber tut etwas anderes. Der tutorial-code schließt die Verbindung, Ihre version commits einer Transaktion. Sie fordern bereits
db.commit()
, so die Aktion ist eigentlich überflüssig, sofern keine Ausnahmen ausgelöst werden.Könnten Sie die Verbindung als einen Kontext-manager erneut, um die automatische Transaktions-handling Verhalten:
Hinweis: die
, db
auf der zweitenwith
Linie, sicherzustellen, dass diedb.__exit__()
Methode wird aufgerufen, wenn der block beendet wird.close()
auf dieconnect_db()
Ergebnis beim beenden, und es gibt das gleiche Objekt aus dercm.__enter__()
Methode, sowith
ordnet, dass der namedb
. Nun, das Objekt selbst ist auch ein context-manager, also in der zweitenwith
wir sorgen dafür, dasswith
Anrufedb.__enter__()
unddb.__exit__()
zu, weil die Steuerung der Transaktion.closing()
Kontext-manager nur Anrufeclose()
nicht an__enter__()
oder__exit__()
(auch wenn das Objekt selbst ist ein context-manager) am Ende des Blocks? Das macht Sinn - vielen Dank für die Zeit nehmen, die Antwort zu einem Kommentar auf so einen alten post.Die einzige Sache, die geschieht durch die
with
- Anweisung ist der Aufruf__enter__
Methode, bevor Sie die Eingabe der block und__exit__
- Methode vor dem beenden es.Wenn diese Methoden nicht definiert sind, die
with
- Anweisung funktioniert nicht wie man erwarten könnte. Ich weiß nicht, was ist der Rückgabetyp vonconnect_db
, aber ich denke, das könnte es werden viele verschiedene Dinge aus verschiedenen Drittanbieter-Bibliotheken. So, dein code ohneclosing
wird wohl in vielen (allen?) Fällen, aber man weiß ja nie was zurückgegeben werden kann, indemconnect_db
.