2016-10-15 2 views
6

Ich dachte, ich könnte meinen Python (2.7.10) -Code einfacher machen, indem ich direkt auf den Index eines Wertes zugreift, der über send an einen Generator übergeben wurde, und war überrascht, dass der Code lief. Ich habe dann einen Index yield angewendet entdeckt hat nicht wirklich etwas zu tun, noch eine Ausnahme wirft:Warum kann Ertrag indiziert werden?

def gen1(): 
    t = yield[0] 
    assert t 
    yield False 

g = gen1() 
next(g) 
g.send('char_str') 

Allerdings, wenn ich zu indizieren yield dreimal versuchen oder mehr, erhalte ich eine Ausnahme:

def gen1(): 
    t = yield[0][0][0] 
    assert t 
    yield False 

g = gen1() 
next(g) 
g.send('char_str') 

die

TypeError: 'int' object has no attribute '__getitem__' 

Das war ungewöhnlich inkonsistentes Verhalten wirft, und ich frage mich, ob es für das, was die Indizierung Ertrag i eine intuitive Erklärung Machst du das eigentlich?

Antwort

13

Sie indexieren nicht. Sie geben eine Liste ab; yield[0] der Ausdruck ist eigentlich nur das gleiche wie die folgenden (aber ohne eine Variable):

lst = [0] 
yield lst 

Wenn Sie schauen, was next() zurückgegeben Sie diese Liste bekommen haben würde:

>>> def gen1(): 
... t = yield[0] 
... assert t 
... yield False 
... 
>>> g = gen1() 
>>> next(g) 
[0] 

Sie don‘ t haben einen Abstand zwischen yield und [0] haben, das ist alles.

Die Ausnahme wird verursacht durch Sie das Abonnement auf die enthaltenen 0 integer anzuwenden versuchen:

>>> [0]  # list with one element, the int value 0 
[0] 
>>> [0][0]  # indexing the first element, so 0 
0 
>>> [0][0][0] # trying to index the 0 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'int' object is not subscriptable 

Wenn Sie einen Wert Index an den Generator gesendet werden soll, setzen Sie Klammern um den yield Ausdruck:

t = (yield)[0] 

Demo:

>>> def gen1(): 
...  t = (yield)[0] 
...  print 'Received: {!r}'.format(t) 
...  yield False 
... 
>>> g = gen1() 
>>> next(g) 
>>> g.send('foo') 
Received: 'f' 
False 
Verwandte Themen