28

方法がわかりませんsend。ジェネレーターの操作に使用されていることを理解しています。ただし、構文は次のとおりですgenerator.send(value)

どういうわけか、値が現在のyield式の結果になる必要がある理由を理解できません。私は例を用意しました:

def gen():
    for i in range(10):
        X = yield i
        if X == 'stop':
            break
        print("Inside the function " + str(X))

m = gen()
print("1 Outside the function " + str(next(m)) + '\n')
print("2 Outside the function " + str(next(m)) + '\n')
print("3 Outside the function " + str(next(m)) + '\n')
print("4 Outside the function " + str(next(m)) + '\n')
print('\n')
print("Outside the function " + str(m.send(None)) + '\n') # Start generator
print("Outside the function " + str(m.send(77)) + '\n')
print("Outside the function " + str(m.send(88)) + '\n')
#print("Outside the function " + str(m.send('stop')) + '\n')
print("Outside the function " + str(m.send(99)) + '\n')
print("Outside the function " + str(m.send(None)) + '\n')

結果は次のとおりです。

1 Outside the function 0

Inside the function None
2 Outside the function 1

Inside the function None
3 Outside the function 2

Inside the function None
4 Outside the function 3



Inside the function None
Outside the function 4

Inside the function 77
Outside the function 5

Inside the function 88
Outside the function 6

Inside the function 99
Outside the function 7

Inside the function None
Outside the function 8

まあ、率直に言って、それは私を驚かせています。

  1. ドキュメントでは、yieldステートメントが実行されると、ジェネレーターの状態がフリーズし、の値がの呼び出し元expression_listに返されることがわかります。nextまあ、それは起こっていないようです。なぜifステートメントとprint関数を内部で実行できるのですかgen()
  2. X関数の内部と外部が異なる理由をどのように理解できますか?Ok。send(77)77をに送信すると仮定しmます。さて、yield式は77になります。では、何X = yield iですか?そして、関数内の77が外部で発生した場合、どのように5に変換されますか?
  3. 最初の結果文字列がジェネレーター内で起こっていることを反映していないのはなぜですか?

sendとにかく、どういうわけかこれらとyieldステートメントについてコメントできますか?

4

5 に答える 5

62

sendジェネレーターでand 式を使用するとyield、それをコルーチンとして扱います。順次インターリーブして実行できますが、呼び出し元とは並列に実行できない別の実行スレッド。

呼び出し元が を実行するR = m.send(a)と、オブジェクトaをジェネレーターの入力スロットに配置し、制御をジェネレーターに転送して、応答を待ちます。ジェネレーターはaの結果としてオブジェクトを受け取り、別の式X = yield iにヒットするまで実行します。次に、出力スロットに入れ、制御を呼び出し元に戻し、再開されるまで待機します。呼び出し元はの結果として受け取り、別のステートメントに到達するまで実行されます。yieldY = yield jjjR = m.send(a)S = m.send(b)

R = next(m)とまったく同じR = m.send(None)です。Noneジェネレーターの入力スロットに入れているので、ジェネレーターがX = yield ithenの結果をチェックすると、XになりますNone

比喩として、口のきけないウェイターを考えてみましょう。

ばかウェイター

サーバーが顧客から注文を受けると、パッドをダムウェイターに置き、sendそれをキッチンに置き、ハッチのそばで料理を待ちます。

R = kitchen.send("Ham omelette, side salad")

シェフ (ハッチのそばで待っていた) が注文を取り、料理を準備し、yieldそれをレストランに渡し、次の注文を待ちます。

next_order = yield [HamOmelette(), SideSalad()]

サーバー(ハッチのそばで待っていた人)が料理を顧客に持って行き、別の注文などで戻ってきます.

sendサーバーとシェフの両方が、注文または料理の後にハッチのそばで待機するためyield、一度に何かを行うのは 1 人だけです。つまり、プロセスはシングル スレッドです。生成機構 (ダム ウェイター) がインターリーブの実行を処理するため、両側で通常の制御フローを使用できます。

于 2012-09-28T10:32:09.880 に答える