yield
Ausdruck gibt die Kontrolle an das zurück, was den Generator verwendet. Der Generator pausiert an dieser Stelle, was bedeutet, dass der @contextmanager
Dekorateur weiß, dass der Code mit dem Setup Teil gemacht wird.
Mit anderen Worten, alles, was Sie im Kontextmanager __enter__
Phase tun möchten, muss vor der yield
stattfinden.
Sobald Ihr Kontext verlässt (so der Block unter der with
Anweisung erfolgt), der @contextmanager
Dekorateur für die __exit__
Teil des Kontextes Manager-Protokoll genannt und wird eines von zwei Dingen tun:
Wenn Es gab keine Ausnahme, es wird Ihren Generator fortsetzen. Also Ihr Generator hebt die Pause an der yield
Linie, und geben Sie die Bereinigungsphase, den Teil
Wenn es eine Ausnahme war, der Dekorateur verwendet generator.throw()
diese Ausnahme im Generator zu erhöhen. Es wird sein, als ob die yield
Zeile diese Ausnahme verursacht hat. Da Sie eine finally
-Klausel haben, wird diese vor dem Beenden des Generators wegen der Ausnahme ausgeführt.
in Ihrem speziellen Beispiel So ist die Reihenfolge wie folgt:
with time_print("processes"):
Dies schafft den Kontext-Manager und fordert __enter__
darauf. Der Generator startet die Ausführung, t = time.time()
wird ausgeführt.
Der Ausdruck yield
pausiert den Generator, die Steuerung geht zurück zum Dekorateur. Dies nimmt, was auch immer geliefert wurde und gibt das an die with
Anweisung zurück, falls es einen as target
Teil gibt.
[doproc() for _ in range(500)]
wird ausgeführt und abgeschlossen.
Der Kontext-Manager __exit__
Methode ausgeführt wird, wird keine Ausnahme bestanden.
Der Dekorateur nimmt den Generator, geht es weiter, wo sie aufgehört haben.
Der finally:
Block wird eingegeben und print task_name, "took", time.time() - t, "seconds."
wird ausgeführt.
Der Generator beendet, der Dekorateur __exit__
Methode beendet, alles ist fertig.
[Aus der Dokumentation:] (https://docs.python.org/2/library/contextlib.html#contextlib.contextmanager) "An dem Punkt, an dem der Generator nachgibt, wird der in der With-Anweisung geschachtelte Block ausgeführt. Der Generator wird dann wieder aufgenommen, nachdem der Block verlassen wurde. Wenn eine unbehandelte Ausnahme im Block auftritt, wird er innerhalb des Generators an diesem Punkt wieder aufgerufen wo der Ertrag aufgetreten ist. " –
"Ausbeute" ohne Argument ist semantisch gleichbedeutend mit "Ausbeute keine" –