正如你所說,yield from
只適用於你想從包裹的發電機通過所有的情況。如果你不希望出現這種情況,您需要手動遍歷包發生器,做你想要什麼:
def b(data):
for value in a(data):
if some_condition(value):
yield value
# otherwise don't yield it.
如果你想處理send
,你需要處理的是自己太。下面是一個簡單的例子,你可以玩的,看看發生了什麼事情:
def a():
sent = yield "Begin"
for x in [1, 2, 3]:
if sent:
sent = yield "You sent {0}".format(sent)
else:
sent = yield x
def b():
gen = a()
val = yield next(gen)
while True:
wrappedVal = gen.send(val)
if wrappedVal == 2:
continue
val = yield wrappedVal
基本上在這個例子中b
「隱藏」的值2,如果它是由a
產生。 (我改編自this question的回答,這類似於包裝發電機,但方式稍有不同。但您可能會發現有用的討論)
但是,您在做這件事時需要非常小心。由於b
可能會跳過a
的值,因此b
可能會跳過意想不到的位置中的值,因此任何嘗試將send
值更改爲b
的呼叫者都可能無法獲得預期的結果。在使用send
的情況下,這通常意味着調用者監視發生器以獲取某些傳遞某些信息的屈服值,然後將值發送回來作爲響應。如果中間有b
,則此通信可能會失去同步。例如,假設a
產生一個「消息」,其中b
產生給呼叫者,並且呼叫者發回響應,然後b
然後發送到a
。但假設b
吞下a
的迴應。這會給調用者帶來問題。您仍然可以使其工作,但這意味着您必須非常小心地編寫b
以主要通過a
的API預期的任何通信渠道。
在你的例子中,'a'只產生一個單一的值。這就是你真正想問的問題,或者你是在想象一個「a」產生很多價值的情況? – BrenBarn
你是對的 - 例子已更新。 – LateCoder