Python 生成器发送:发送后不产生新值

vge*_*gel 8 python yield generator yield-keyword coroutine

这是一个奇怪的问题,所以我将解释:

我有一个像这样的生成器,它充当 IRC 服务器的生成器前端:

def irc_iter(): # not the real code, simplified
    msgs = get_msgs()
    for msg in msgs:
        if is_ping(msg):
            pong()
        else:
            to_send = yield msg
            for s in to_send:
                send(s)
Run Code Online (Sandbox Code Playgroud)

从理论上讲,这应该允许我做一些很酷的事情,例如:

server = connect()
for line in server:
       if should_respond(line):
           server.send('WOW SUCH MESSAGE')
Run Code Online (Sandbox Code Playgroud)

但是,有一个问题:也会generator.send 产生下一个值。这意味着这server.send也给了我下一条消息......我更愿意像所有其他消息一样处理它,产生为line.

我知道我可以用一种丑陋的方式来解决这个问题,在接收到发送后只产生一个垃圾值,但我试图保持我的代码优雅,但恰恰相反。有没有办法告诉生成器我还不需要新值?

谢谢。

bj0*_*bj0 1

看起来问题来自于每次迭代调用生成器两次,一次 with .send(None)(在 for 循环中),一次 with .send(response)

如果 for 循环可以迭代 .send() 而不是 .next(),这将是一个简单的修复,但我不熟悉任何使其工作的方法(pep342 中的可选扩展 continue 语句?)而不将其包装在另一个生成器(可能使用队列在 .next() 调用时将值推送到 .send() 中)。不过,最简单的解决方案可能是:

server = connect()
response = None 
try:
    while True:
        line = server.send(response)
        response = None
        if should_respond(line):
            response ='WOW SUCH MESSAGE'
except StopIteration:
    pass
Run Code Online (Sandbox Code Playgroud)