繁体   English   中英

在 python 中使用带条件的 yield from

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM