2016-10-15 9 views
6

私は、sendでジェネレータに渡された値のインデックスに直接アクセスしてPython(2.7.10)コードを簡単に作ることができ、コードが実行されたことに驚いたと思いました。私は、本当に何もしない、またそれが例外をスローしないインデックスはyieldに適用発見:なぜ産出がインデックスに登録されるのですか?

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

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

私はインデックスyield三度以上にしようとした場合しかし、私は例外を取得:

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

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

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

これは非常に一貫性のない行動だった、そしてどのようなインデックス降伏私のための直感的な説明がある場合、私は思っていたがスローされます

実際にやっている?

答えて

13

インデックスを作成していません。あなたはリストを作成しています。表現yield[0]は本当に、次の(しかし、変数なし)として全く同じである:

lst = [0] 
yield lst 

あなたはnext()は、あなたがそのリストを得ていると思い返されたものを見れば:

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

あなたがドン」 t はと[0]の間のスペースを持つです。あなたがインデックスに発電機に送られた値を使用する場合は

>>> [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 

は、yield表現の前後に括弧を挿入:

例外は、あなたが含まれている0整数にサブスクリプションを適用しようとによって引き起こされます

t = (yield)[0] 

デモ:

>>> def gen1(): 
...  t = (yield)[0] 
...  print 'Received: {!r}'.format(t) 
...  yield False 
... 
>>> g = gen1() 
>>> next(g) 
>>> g.send('foo') 
Received: 'f' 
False 
関連する問題