考虑以下伪代码:
def g_user():
while True:
yield read_user_input()
def g_socket():
while True:
yield read_socket_input()
def g_combined(gu, gs):
# should read user or socket input, whichever is available
while True:
sel = select(gu, gs)
if sel.contains(gu):
yield gu.next()
if sel.contains(gs):
yield gs.next()
gc = g_combined ( g_user(), g_socket() )
如何以最简单的方式实现这一目标?
答案 0 :(得分:8)
看起来就像有人已经实现了这个:http://www.dabeaz.com/generators/genmulti.py
在这里反映:
import Queue, threading
def gen_multiplex(genlist):
item_q = Queue.Queue()
def run_one(source):
for item in source: item_q.put(item)
def run_all():
thrlist = []
for source in genlist:
t = threading.Thread(target=run_one,args=(source,))
t.start()
thrlist.append(t)
for t in thrlist: t.join()
item_q.put(StopIteration)
threading.Thread(target=run_all).start()
while True:
item = item_q.get()
if item is StopIteration: return
yield item
答案 1 :(得分:1)
为了使select.select()
正常工作,您需要在生成器上公开一个返回基础文件描述符的fileno()
方法。
答案 2 :(得分:-2)
标准库中的itertools模块包含很好的函数。在这种特殊情况下,循环功能很好。
循环帮助说:循环(可迭代) - >循环对象
从迭代中返回元素,直到它耗尽为止。然后 无限期地重复序列。
在解决方案中使用循环:
import itertools
def g_user():
while True:
yield read_user_input()
def g_socket():
while True:
yield read_socket_input()
def g_combine(*generators):
for generator in itertools.cycle(generators):
yield generator.next()
g_combined = g_combine(g_user(), g_socket())
关于此代码的注意事项:
g_combine以第一个引发StopIteration
g_combine接受N个生成器
如何正确捕获异常?想一想。