[英]Using yield from with conditional in python
假设我有一个这样的生成器:
def a(data):
for val in data:
yield val
让说,我想在另一个发电机,来包装这个发生器b
,只产生一些来自值的a
,这取决于它们的价值。 b
应该能够将从调用者发回的值转发到a
。 我知道将生成器包装在另一个生成器中的最新方法是使用yield from
语句。 就像是:
def b(data):
yield from val = a(data) if val == "foo"
我知道语法是错误的(只是为了理解这个想法),所以我想知道是否有正确的方法可以使用条件语句使工作yield from
。 或者我应该使用其他一些构造吗?
正如您所说, 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
产生a
。 (我根据我对这个问题的回答改编了这个,这与包装生成器类似,但方式略有不同。不过,您可能会发现那里的讨论很有用。)
但是,您在执行此操作时需要非常小心。 由于b
可以跳过值a
,任何调用方试图send
值到b
可能无法获得预期的结果,因为b
可能在意想不到的地方会跳过值。 在您使用send
情况下,这通常意味着调用者会监视生成器中某些传递某些信息的生成值,然后将值发送回作为响应。 如果b
在中间,这种通信可能会不同步。 例如,假设a
产生一条“消息”, b
将其交给调用者,调用者发回响应,然后b
将响应发送给a
。 但是假设b
吞下a
的响应。 这会给调用者带来问题。 您可能仍然能够让它工作,但它只是意味着你必须以书面形式非常小心b
通过的API中预期的任何主要的沟通渠道a
。
由于看起来我无法将条件合并到yield from
,我通过手动处理我关心的情况解决了这个问题。 这就是我最终的结果:
def a():
data = get_data_somewhere()
for val in data:
yield val
def b():
a_gen = a()
val = next(a_gen)
try:
while True:
if val == "foo":
received = yield val
val = a_gen.send(received)
else:
val = a_gen.send(None)
except StopIteration:
pass
finally:
del a_gen
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.