2017-02-07 1 views
0

Ich habe die folgende Funktion,Wird `mit Öffnen ... als Datei` Datei schließen, wenn innerhalb des eingerückten Blocks ein Wert zurückgegeben wird?

def load(): 
    with open(PATH_CONFIG, 'r') as file: 
     return json.loads(file.read()) 

Wird es eine file.close() genannt werden? Ich weiß, dass das with Schlüsselwort normalerweise die close() Methode für die Datei am Ende des eingerückten Blocks, aber zur gleichen Zeit das return Schlüsselwort bedeutet, dass der Rest der Funktion nicht ausgeführt wird.

+0

Nun, die 'return' bringt Sie aus dem Kontextmanager von' file' ... –

+0

'return' bedeutet, dass die nächsten Anweisungen nicht ausgeführt werden, und der Kontrollfluss verlässt die aktuelle Funktion. Das bedeutet nicht, dass auf dem Weg nach draußen nichts passiert. Locals werden immer noch freigegeben, Ausnahmen 'open 'finally' und 'else' -Klauseln werden immer noch ausgeführt und ... '__exit__' von Kontextmanagern werden immer noch aufgerufen. – spectras

Antwort

2

Genau wie try/finally, etwas, der die with Block verlässt (return, break/continue, die eine Schleife um ihn herum beeinflusst, Ausnahme ausgelöst, sys.exit genannt, usw.) wird eine geeignete Säuberung durchführen, da die Ausführungsblasen aus dem with Block hervorgehen.

Die einzigen Ausnahmen sind:

  1. Wenn es tatsächlich Fehler (im Interpreter oder in dem Missbrauch von eigen gefährlichen Werkzeugen wie ctypes), wo der Interpreter selbst abstürzt oder auf andere Weise beendet „zwangsweise“ (zB durch ein segfault)
  2. os._exit Aufruf umgeht alle Bereinigungsverfahren (das ist, warum es nie in irgendetwas verwendet werden sollte, aber worker-Prozesse gegabelt)
0

Return verlässt der mit Block wie ein normaler Dedent

0

Ja.

Wenn eine Ausnahme ausgelöst wird, hat ein Kontextmanager die Möglichkeit, sein Verhalten zu ändern, aber es gibt keinen Unterschied zwischen einer Rückgabe und dem Abfallen vom Ende des Anweisungskörpers. Mit wenigen Ausnahmen führen die meisten Kontextmanager ihre Bereinigung durch Erlaube der Ausnahme zu propagieren.

Die Idee ist, dass es mit einer finally-Anweisung vergleichbar ist und ausgeführt wird, egal wie der Block beendet wird. Die contextmanager Klasse aus der Standardbibliothek macht diese Analogie konkret.

from contextlib import contextmanager 
@contextmanager 
def example(): 
    print('enter') 
    try: 
     yield 
     print('unexceptional return') 
    finally: 
     print('exit') 

Wir with example(): auf verschiedene Weise nutzen, um zu sehen, wie die mit Anweisung in einem sichtbaren Beispiel wird als eine Datei geschlossen wird.

Verwandte Themen