Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python生成器send:don';t在发送后生成新值_Python_Generator_Yield_Coroutine_Yield Keyword - Fatal编程技术网

Python生成器send:don';t在发送后生成新值

Python生成器send:don';t在发送后生成新值,python,generator,yield,coroutine,yield-keyword,Python,Generator,Yield,Coroutine,Yield Keyword,这是一个奇怪的问题,所以我会解释: 我有一个这样的生成器,充当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_

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

我有一个这样的生成器,充当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)
从理论上讲,这应该允许我做一些很酷的事情,比如:

server = connect()
for line in server:
       if should_respond(line):
           server.send('WOW SUCH MESSAGE')
但是,有一个问题:
generator.send
也会生成下一个值。这意味着
server.send
也会给我下一条消息。。。我更愿意像处理所有其他消息一样处理它,生成为
line

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


谢谢。

问题似乎来自您在每次迭代中调用生成器两次,一次使用
.send(None)
(在for循环中)和一次使用
.send(response)

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

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

我也遇到了这个问题,也没有发现比dummy
yield
更好的东西

因此,在生成器代码中:

        # Input
        input_value = yield
        if input_value is None:
            # Handle situation if someone used your generator in a wrong way
            sys.exit(-1)
        yield "DUMMY YIELD JUST STOP HERE!!!"
在客户端代码中:

while True:
    values = next(my_generator)
    ...
    if values == 'INPUT_NEEDED':
        # At this point you realize it's input time
        next(my_generator) # Rewind to the input point
        my_generator.send(12345) # Returns "DUMMY YIELD JUST STOP HERE!!!"
        continue
    # Continue the main loop

我不确定我是否知道问题出在哪里。从服务器获取数据与向服务器发送数据是不同的。你真的需要两个协程吗?不幸的是,是的,我经常在我的协程中加入裸露的
yield
语句,当它们是半迭代器、半协程的“复合”风格时。我已经成功地重写了这样的消费者,使其始终显式地
发送
,即使大部分时间我都没有发送。不确定这是否对您有帮助,但这是一个想法。@IfLoop但与服务器通信与通信是一样的。。。使用服务器。通信的方向已经清楚地表示为数据进出协同路由的方向。为什么要拆分它呢?因为python中的生成器没有不同的
send()
next()
send()
只是带有一个参数的
next()
。这种解决方案很有效,但并不比只使用一个伪
yield
要好多少。我希望有一个简单的替代方法调用或库可以处理这个问题。