Ich lese über das Schlüsselwort yield
in Python und versuche zu verstehen, wie dieses Beispiel ausgeführt wird:
Die Ausgabe ist:
%Vor%Es sieht so aus, als würde die Ausbeute den angegebenen Wert zurückgeben und die Funktion bis zum Ende (in einem parallelen Thread vielleicht) fortsetzen. Ist mein Verständnis korrekt?
Wenn Sie das beantworten könnten, ohne "Generatoren" zu erwähnen, wäre ich dankbar, weil ich versuche, eins nach dem anderen zu verstehen.
Nein, es gibt nur einen einzigen Thread.
Jede Iteration der for-Schleife führt Ihre countFrom
-Funktion aus, bis sie etwas ergibt oder zurückkehrt. Nach der Ausbeute wird der Rumpf der for-Schleife erneut ausgeführt und dann, wenn eine neue Iteration beginnt, nimmt die Funktion countFrom
genau dort wieder auf, wo sie aufgehört hat, und läuft erneut, bis sie nachgibt (oder zurückkehrt).
Diese modifizierte Version Ihres Beispiels wird hilfreich dabei helfen, die Ausführung des Pfades klarer zu machen.
%Vor%Ausgabe
%Vor% Sie können sich das so vorstellen, als würde die Funktion yield
s einfach "pausieren", wenn sie auf .next()
stößt. Wenn Sie es das nächste Mal aufrufen, wird es nach dem .next()
fortgesetzt und behält den Status bei, in dem es sich befand, als es verlassen hat.
Nein, es gibt nur einen einzigen Thread.
Jede Iteration der for-Schleife führt Ihre .next()
-Funktion aus, bis sie etwas ergibt oder zurückkehrt. Nach der Ausbeute wird der Rumpf der for-Schleife erneut ausgeführt und dann, wenn eine neue Iteration beginnt, nimmt die Funktion .next()
genau dort wieder auf, wo sie aufgehört hat, und läuft erneut, bis sie nachgibt (oder zurückkehrt).
Diese modifizierte Version Ihres Beispiels wird hilfreich dabei helfen, die Ausführung des Pfades klarer zu machen.
%Vor%Ausgabe
%Vor% Die Funktion yield
wird nicht in einem parallelen Thread ausgeführt. Was passiert hier, wenn die %code% -Konstruktion nach dem nächsten Wert fragt, wird die Funktion ausgeführt, bis sie eine %code% -Anweisung trifft. Wenn der nächste Wert danach benötigt wird, setzt die Funktion die Ausführung dort fort, wo sie unterbrochen wurde.
Und während Sie gebeten haben, "Generatoren" nicht zu erwähnen, sind sie so eng mit %code% verbunden, dass es nicht wirklich Sinn macht, darüber getrennt zu sprechen. Was Ihre %code% -Funktion tatsächlich zurückgibt, ist ein "Generator-Objekt". Sie gibt dieses Objekt unmittelbar nach dem Aufruf zurück, so dass der Funktionskörper überhaupt nicht ausgeführt wird, bis etwas (z. B. %code% -loop) Werte vom Generator mit seiner Methode %code% anfordert.
Die Yield-Anweisung speichert den Wert, den Sie erhalten, bis diese Funktion erneut aufgerufen wird. Wenn Sie also diese Funktion (mit einem Iterator) aufrufen, wird die Funktion ein anderes Mal ausgeführt und Sie erhalten den Wert. Der Punkt ist, dass es weiß, wo es beim letzten Mal aufgehört hat.
Ich lese über das Schlüsselwort %code% in Python und versuche zu verstehen, wie dieses Beispiel ausgeführt wird:
%Vor%Die Ausgabe ist:
%Vor%Es sieht so aus, als würde die Ausbeute den angegebenen Wert zurückgeben und die Funktion bis zum Ende (in einem parallelen Thread vielleicht) fortsetzen. Ist mein Verständnis korrekt?
Wenn Sie das beantworten könnten, ohne "Generatoren" zu erwähnen, wäre ich dankbar, weil ich versuche, eins nach dem anderen zu verstehen.
Python wird ausgeführt, bis es auf %code% trifft, und stoppt dann und stoppt die Ausführung. Es läuft nicht weiter. Beim nächsten Aufruf von %code%
wird "nach" gedrücktDas ist leicht zu sagen, ohne auf Generatoren Bezug zu nehmen, aber Tatsache ist, dass Ertrag und Generator untrennbar miteinander verbunden sind. Um es wirklich zu verstehen, müssen Sie sie als das gleiche Thema betrachten.
Es ist einfach, sich selbst zu zeigen, dass das, was ich (und andere) gesagt habe, wahr ist, wenn man mit dem Generator auf eine manuellere Weise von deinem Beispiel aus arbeitet.
Eine Funktion, die %code% s anstelle von %code% ing tatsächlich einen Generator zurückgibt. Sie können diesen Generator dann konsumieren, indem Sie %code% aufrufen. Sie sind verwirrt, weil Ihre Schleife sich um alles kümmert, was im Hintergrund für Sie ist.
Hier ist es mit den Interna geöffnet:
%Vor% Die Funktion countfrom
wird nicht in einem parallelen Thread ausgeführt. Was passiert hier, wenn die for
-Konstruktion nach dem nächsten Wert fragt, wird die Funktion ausgeführt, bis sie eine yield
-Anweisung trifft. Wenn der nächste Wert danach benötigt wird, setzt die Funktion die Ausführung dort fort, wo sie unterbrochen wurde.
Und während Sie gebeten haben, "Generatoren" nicht zu erwähnen, sind sie so eng mit yield
verbunden, dass es nicht wirklich Sinn macht, darüber getrennt zu sprechen. Was Ihre countfrom
-Funktion tatsächlich zurückgibt, ist ein "Generator-Objekt". Sie gibt dieses Objekt unmittelbar nach dem Aufruf zurück, so dass der Funktionskörper überhaupt nicht ausgeführt wird, bis etwas (z. B. for
-loop) Werte vom Generator mit seiner Methode .next()
anfordert.
Die Yield-Anweisung speichert den Wert, den Sie erhalten, bis diese Funktion erneut aufgerufen wird. Wenn Sie also diese Funktion (mit einem Iterator) aufrufen, wird die Funktion ein anderes Mal ausgeführt und Sie erhalten den Wert. Der Punkt ist, dass es weiß, wo es beim letzten Mal aufgehört hat.
Python wird ausgeführt, bis es auf yield
trifft, und stoppt dann und stoppt die Ausführung. Es läuft nicht weiter. Beim nächsten Aufruf von countfrom
Das ist leicht zu sagen, ohne auf Generatoren Bezug zu nehmen, aber Tatsache ist, dass Ertrag und Generator untrennbar miteinander verbunden sind. Um es wirklich zu verstehen, müssen Sie sie als das gleiche Thema betrachten.
Es ist einfach, sich selbst zu zeigen, dass das, was ich (und andere) gesagt habe, wahr ist, wenn man mit dem Generator auf eine manuellere Weise von deinem Beispiel aus arbeitet.
Eine Funktion, die yield
s anstelle von return
ing tatsächlich einen Generator zurückgibt. Sie können diesen Generator dann konsumieren, indem Sie next
aufrufen. Sie sind verwirrt, weil Ihre Schleife sich um alles kümmert, was im Hintergrund für Sie ist.
Hier ist es mit den Interna geöffnet:
%Vor%