yield
リターンそのオブジェクトがシーケンス、ジェネレータまたはその他のイテレータであっても、渡されるオブジェクトは何でもしたがって:(それはfor x in obj
構築物の一部である場合のように)オブジェクトのコンテンツ反復子が必要とされる場合
>>> def g():
... yield [1,2,3]
... yield 1
... yield 2
... yield 3
...
>>> gen = g()
>>> gen.next()
[1, 2, 3]
>>> gen.next()
1
>>> gen.next()
2
>>> gen.next()
3
>>> gen.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
__iter__
は、オブジェクト上で呼び出されます。 yield
を使用すると(ジェネレータはイテレータなので)ジェネレータを作成できますが、この例では必要ありません。以下は同様に動作します:
def __iter__(self):
return iter(self.__a)
あなたがyield
を使用したい、とあなたはVect
オブジェクトがベクトルの内容を移動するためのイテレータをしたい場合は、収率に持っている各値を別々:
def __iter__(self):
for i in self.__a:
yield i
yield
は__iter__
は、発電機を返すことを意味し、ジェネレータオブジェクトにnext()
を呼び出すと、それは__a
を反復処理として、それは最後の、オフに左の点で機能を再開します。
======= Pythonはどこにある発電機の実行中に追跡する方法に関する追加質問に対して
が、私はそれがf_lastiを使用すると信じて(==「最後の命令」)のジェネレータのgi_frame属性(ジェネレータは、通常の関数とは異なり、それらのジェネレータの周りに実行フレームを持ちます)。ここでその周りに工具のビット値がどのように変化するかを示します:
>>> import dis
>>> def g():
... yield 1
... for i in range(10):
... yield i*2
...
>>> gen = g()
>>> dis.dis(gen.gi_code)
2 0 LOAD_CONST 1 (1)
3 YIELD_VALUE
4 POP_TOP
3 5 SETUP_LOOP 29 (to 37)
8 LOAD_GLOBAL 0 (range)
11 LOAD_CONST 2 (10)
14 CALL_FUNCTION 1
17 GET_ITER
>> 18 FOR_ITER 15 (to 36)
21 STORE_FAST 0 (i)
4 24 LOAD_FAST 0 (i)
27 LOAD_CONST 3 (2)
30 BINARY_MULTIPLY
31 YIELD_VALUE
32 POP_TOP
33 JUMP_ABSOLUTE 18
>> 36 POP_BLOCK
>> 37 LOAD_CONST 0 (None)
40 RETURN_VALUE
>>> gen.gi_frame.f_lasti ## -1 because we haven't started yet
-1
>>> gen.next()
1
>>> gen.gi_frame.f_lasti
3
>>> gen.gi_frame.f_locals
{}
>>> gen.next()
0
>>> gen.gi_frame.f_lasti , gen.gi_frame.f_locals
(31, {'i': 0})
>>> gen.next()
2
>>> gen.gi_frame.f_lasti , gen.gi_frame.f_locals
(31, {'i': 1})
>>>
注f_lasti値が最後の収率が上であったことをことを逆アセンブルコードに番号の行に対応する方法:ときに発生その時点から再開し再入力されます。
yield文を使用するメソッドは、イテレータです。返される値は、イテレータによってアクセスされる値です。 – robert
ところで、あなたは、Pythonがイテレータによって最後に返された要素をどのように記憶しているかを知っていますか? – Michal
"私の例ではジェネレータがありません" - yieldステートメントを含む関数はジェネレータです。あなたは何が必要なのですか?ジェネレータ**の式**?それは1つの種類の発電機に過ぎません。 –