2

Pythonジェネレーターの微妙な詳細のいくつかを理解しようとしています。同じジェネレーターとの間で値を交互に送受信できるかどうかを確認するために作成したテスト プログラムの 1 つを次に示します。

def injector():
    while True:
        try:
            print 'a'
            v = yield
            print 'b', v
            yield v
            print 'c'
        except GeneratorExit:
            print 'exit'
            break

g = injector()

print 'send none'
g.send(None)
print 'send 2'
g.send(2)
print 'receiving'
v = g.next()
print 'received', v

g.close()

このプログラムの期待される出力は次のとおりです。

send none
a
send 2
b 2
receiving
received 2
c
a
exit

私が得る出力は次のとおりです。

send none
a
send 2
b 2
receiving
c
a
received None
exit

さて、明らかに、問題はなぜ上記の出力が得られるのかということです。ジェネレーターの仕組みについて理解できなかったのは何ですか?

4

2 に答える 2

3

明確にしてみましょう:

def injector():
    while True:
        try:
            print 'a'
            v = yield
            print 'b', v
            yield v
            print 'c'
        except GeneratorExit:
            print 'exit'
            break

g = injector()

print 'send none'
g.send(None)

ここでコルーチンが開始されます。結果が から返される最初の yield まで実行され.send()ますが、その後は破棄されます。

したがって、コルーチンaは何も出力せず、生成しませんNone。なので捨ててもOK。

print 'send 2'
g.send(2)

ここでは、コルーチンに 2 を送信して、コルーチンを終了した場所から継続させます。v = 2.

それは印刷され、再び2生成vされます。g.send()あなたは電話からそれを期待するでしょう。したがって、 を受け取って破棄した後v

print 'receiving'
v = g.next()

ここで、再びコルーチンに制御を渡します。コルーチンは を出力しc、次にを出力し、再びa生成Noneします。これをここで取得します。

print 'received', v

したがって、 が出力Noneされvます。

おそらくあなたが望むのは

g = injector()

print 'send none'
g.send(None)
print 'send 2'
v = g.send(2)
print 'received', v

g.close()

(この最後のブロックは、次のように、よりきれいに適切に記述できることに注意してください。

from contextlib import closing
with closing(injector()) as g:
    print 'send none'
    g.send(None)
    print 'send 2'
    v = g.send(2)
    print 'received', v

)

于 2012-11-29T13:11:01.607 に答える
0

したがって、あなたが抱えている問題は最後の電話です。まず第一に、コードが中断したところから開始しているように見え、'c'最初に出力されます。その後、ステートメントが生成されなかったので、while ループを継続して印刷し'a'ます。最後に、出力が生成されます。の後に何も生成されないため、 none が発生します。'a'

于 2012-11-29T13:02:39.473 に答える