我有一个生成器,每次迭代运行需要很长时间.是否有标准的方法让它产生一个值,然后在等待再次调用时生成下一个值?
每次在gui中按下按钮时都会调用生成器,并且每次按下按钮后,用户都应该考虑结果.
编辑:解决方法可能是:
def initialize():
res = next.gen()
def btn_callback()
display(res)
res = next.gen()
if not res:
return
Run Code Online (Sandbox Code Playgroud)
不.发电机不是异步的.这不是多处理.
如果您想避免等待计算,则应使用该multiprocessing程序包,以便独立的进程可以进行昂贵的计算.
您需要一个单独的过程来计算和排队结果.
然后,您的"生成器"可以简单地将可用结果出列.
如果我想做一些像你的解决方法,我会写一个这样的类:
class PrefetchedGenerator(object):
def __init__(self, generator):
self._data = generator.next()
self._generator = generator
self._ready = True
def next(self):
if not self._ready:
self.prefetch()
self._ready = False
return self._data
def prefetch(self):
if not self._ready:
self._data = self._generator.next()
self._ready = True
Run Code Online (Sandbox Code Playgroud)
它比你的版本更复杂,因为我做了它,因此它处理不会调用prefetch或调用prefetch太多次.基本的想法是,当你想要下一个项目时,你可以调用.next().你有"时间"杀死时调用prefetch.
你的另一个选择是一个线程..
class BackgroundGenerator(threading.Thread):
def __init__(self, generator):
threading.Thread.__init__(self)
self.queue = Queue.Queue(1)
self.generator = generator
self.daemon = True
self.start()
def run(self):
for item in self.generator:
self.queue.put(item)
self.queue.put(None)
def next(self):
next_item = self.queue.get()
if next_item is None:
raise StopIteration
return next_item
Run Code Online (Sandbox Code Playgroud)
这将与您的主应用程序分开运行.无论获取每次迭代需要多长时间,您的GUI都应保持响应.