yield は単なるジェネレーターです。ジェネレーターは、最後に返されたときの関数本体内の位置を記憶する関数です。ジェネレーター関数の 2 番目 (または n 番目) の呼び出しは、関数の途中にジャンプし、すべてのローカル変数は前の呼び出しから変更されないままになります。
ジェネレーターは関数です
関数のすべてのパラメータは保持されます
この関数が2回目に呼び出されるとき
使用されたパラメータは前回から保持されます
ジェネレータもそれを「記憶」しますフロー制御
ジェネレーターの構築は、そのデータ状態を単に「記憶」するだけではありません。 ジェネレーターは、フロー制御構造内の位置も「記憶」します (命令型プログラミングでは、この構造は単なるデータ値ではありません)。継続性は、(ジェネレーターと同様に) 常に直接の呼び出し元のコンテキストに戻ることなく、実行フレーム間を任意にジャンプできるため、依然として比較的一般的です。
yieldジェネレーターの動作メカニズム
ジェネレーターに数値を要求すると、ジェネレーターはyieldステートメントが表示されるまで実行され、その後ジェネレーターは実行を継続しません。 次の数字を尋ねると、彼は最後の状態から実行を開始し、yield ステートメントが表示されるまで実行し、パラメータを指定して停止します。関数が終了するまでこれを繰り返します。
例: Python 順列、組み合わせジェネレーター
#完全な順列を生成
def perm(items, n=None): if n is None: n = len(items) for i in range(len(items)): v = items[i:i+1] if n == 1: yield v else: rest = items[:i] + items[i+1:] for p in perm(rest, n-1): yield v + p
#組み合わせを生成
def comb(items, n=None): if n is None: n = len(items) for i in range(len(items)): v = items[i:i+1] if n == 1: yield v else: rest = items[i+1:] for c in comb(rest, n-1): yield v + c a = perm('abc') for b in a: print b break print '-'*20 for b in a: print b
結果は次のとおりです:
102 pvopf006 ~/test> ./generator.py
abc
- -- ------------------
acb
bac
bca
cab
cba
ご覧のとおり、最初のループの中断後、ジェネレーターは「続行しない」が実行され、最初のループの後に 2 番目のループが実行されます