Code: Alles auswählen
def gen(value):
while True:
value = yield value
Code: Alles auswählen
In [8]: g = gen('foo')
In [9]: print g.send(None)
foo
In [10]: print g.send('bar')
bar
In [11]: print g.next()
None
Code: Alles auswählen
def gen(value):
while True:
value = yield value
Code: Alles auswählen
In [8]: g = gen('foo')
In [9]: print g.send(None)
foo
In [10]: print g.send('bar')
bar
In [11]: print g.next()
None
Code: Alles auswählen
>>> def gen(value):
... while True:
... print('pre-yield', value)
... value = yield value
... print('post-yield', value)
...
>>> g = gen('foo')
>>> g.send(None)
pre-yield foo
'foo'
>>> g.send('bar')
post-yield bar
pre-yield bar
'bar'
>>> next(g)
post-yield None
pre-yield None
Code: Alles auswählen
#
1 3 2
| | |
def gen(value):| | |
while True:____| |
value =|yield value|
1: g = gen(1)
2: g.send(None)
3: g.send(2)
Graphisch gesprochen wertet der Generator das Statement rechts von 'yield' aus, gibt es an den Aufrufer zurück und pausiert dann quasi rechts vor dem "=". Nach dem "Wiederanstupsen" steht da dann im Prinzip "value = None", wenn das Anstupsen mit next() erfolgt resp. value = <x im Ausdruck 'gen.send(x)'>, wenn man 'send' verwendet. Dann wird der Code wieder bis zum Gleichheitszeichen ausgeführt. So erkläre ich mir das zumindest.mutetella hat geschrieben:Wo findet die Zuweisung zu `value` statt?
Beziehungsweise, hat `value` nach seiner Zuweisung und der Rückgabe noch denselben Wert und wird erst dann auf `None` gesetzt, wenn der folgende Stupser keinen Wert mitbringt?
Code: Alles auswählen
In [1]: def gen(value):
...: while True:
...: value = yield value
...:
In [2]: import dis
In [3]: dis.dis(gen)
2 0 SETUP_LOOP 17 (to 20)
>> 3 LOAD_GLOBAL 0 (True)
6 POP_JUMP_IF_FALSE 19
3 9 LOAD_FAST 0 (value)
12 YIELD_VALUE
13 STORE_FAST 0 (value)
16 JUMP_ABSOLUTE 3
>> 19 POP_BLOCK
>> 20 LOAD_CONST 0 (None)
23 RETURN_VALUE
was für mich so aussieht, als ob TOS sowas wie eine Liste von Konstanten, Namen und Referenzen ist, dann steht in der Doku aber wiederLOAD_GLOBAL(namei)
Loads the global named co_names[namei] onto the stack.
LOAD_FAST(var_num)
Pushes a reference to the local co_varnames[var_num] onto the stack.
was ja danach aussieht, als ob hier nicht einzelne Elemente aus dem TOS, sondern der gesamte TOS betroffen ist. Also `YIELD_VALUE()` beispielsweise gibt den gesamten TOS zurück, was ja nicht sein kann, wenn dieser TOS eine Liste, so wie in meiner Vorstellung, wäre.YIELD_VALUE()
Pops TOS and yields it from a generator.
STORE_FAST(var_num)
Stores TOS into the local co_varnames[var_num].