Python生成器预取?

foo*_*ion 5 python generator

我有一个生成器,每次迭代运行需要很长时间.是否有标准的方法让它产生一个值,然后在等待再次调用时生成下一个值?

每次在gui中按下按钮时都会调用生成器,并且每次按下按钮后,用户都应该考虑结果.

编辑:解决方法可能是:

def initialize():
    res = next.gen()

def btn_callback()
    display(res)
    res = next.gen()
    if not res:
       return
Run Code Online (Sandbox Code Playgroud)

S.L*_*ott 7

不.发电机不是异步的.这不是多处理.

如果您想避免等待计算,则应使用该multiprocessing程序包,以便独立的进程可以进行昂贵的计算.

您需要一个单独的过程来计算和排队结果.

然后,您的"生成器"可以简单地将可用结果出列.


Win*_*ert 6

如果我想做一些像你的解决方法,我会写一个这样的类:

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都应保持响应.