Folgendes berücksichtigen:
with open(path, mode) as f:
return [line for line in f if condition]
Wird die Datei ordnungsgemäß geschlossen oder wird returnder Kontextmanager irgendwie umgangen ?
Folgendes berücksichtigen:
with open(path, mode) as f:
return [line for line in f if condition]
Wird die Datei ordnungsgemäß geschlossen oder wird returnder Kontextmanager irgendwie umgangen ?
Antworten:
Ja, es verhält sich wie ein finallyBlock nach dem anderen try, dh es wird immer ausgeführt (es sei denn, der Python-Prozess wird natürlich auf ungewöhnliche Weise beendet).
Es wird auch in einem der Beispiele von PEP-343 erwähnt, das die Spezifikation für die withAussage ist:
with locked(myLock):
# Code here executes with myLock held. The lock is
# guaranteed to be released when the block is left (even
# if via return or by an uncaught exception).
Erwähnenswert ist jedoch, dass Sie Ausnahmen, die durch den open()Aufruf ausgelöst werden, nicht einfach abfangen können , ohne den gesamten withBlock in einen try..exceptBlock zu setzen, der normalerweise nicht das ist, was man will.
Process.terminate()ist es eines der wenigen (einzigen?) Szenarien, die den Aufruf einer finallyAnweisung nicht garantieren : "Beachten Sie, dass Exit-Handler und schließlich Klauseln usw.
withBlock zurückgebe, bleibt die Garantie so lange bestehen, wie der Generator weiterhin Werte liefert? solange irgendetwas darauf verweist? Muss ich delder Variablen, die das Generatorobjekt enthält, einen anderen Wert verwenden oder einen anderen Wert zuweisen?
ValueError: I/O operation on closed file..
Ja.
def example(path, mode):
with open(path, mode) as f:
return [line for line in f if condition]
..ist ziemlich gleichbedeutend mit:
def example(path, mode):
f = open(path, mode)
try:
return [line for line in f if condition]
finally:
f.close()
Genauer gesagt wird die __exit__Methode in einem Kontextmanager beim Verlassen des Blocks immer aufgerufen (unabhängig von Ausnahmen, Rückgaben usw.). Die __exit__Methode des Dateiobjekts ruft nur auf f.close()(z. B. hier in CPython ).
finallySchlüssel erhalten, ist : def test(): try: return True; finally: return False.
Ja. Im Allgemeinen wird die __exit__Methode eines With Statement Context Managers tatsächlich aufgerufen, wenn ein returnKontext innerhalb des Kontexts angezeigt wird . Dies kann mit folgendem getestet werden:
class MyResource:
def __enter__(self):
print('Entering context.')
return self
def __exit__(self, *exc):
print('EXITING context.')
def fun():
with MyResource():
print('Returning inside with-statement.')
return
print('Returning outside with-statement.')
fun()
Die Ausgabe ist:
Entering context.
Returning inside with-statement.
EXITING context.
Die obige Ausgabe bestätigt, dass __exit__trotz des frühen aufgerufen wurde return. Daher wird der Kontextmanager nicht umgangen.
Ja, aber in anderen Fällen kann es zu Nebenwirkungen kommen, da im __exit__Block möglicherweise etwas getan werden sollte (z. B. das Löschen des Puffers)
import gzip
import io
def test(data):
out = io.BytesIO()
with gzip.GzipFile(fileobj=out, mode="wb") as f:
f.write(data)
return out.getvalue()
def test1(data):
out = io.BytesIO()
with gzip.GzipFile(fileobj=out, mode="wb") as f:
f.write(data)
return out.getvalue()
print(test(b"test"), test1(b"test"))
# b'\x1f\x8b\x08\x00\x95\x1b\xb3[\x02\xff' b'\x1f\x8b\x08\x00\x95\x1b\xb3[\x02\xff+I-.\x01\x00\x0c~\x7f\xd8\x04\x00\x00\x00'
elsekönnte hinzugefügt werdenwith, um diesestry with exceptProblem zu lösen . bearbeiten: zur Sprache hinzugefügt