暂停Python生成器

3 投票
4 回答
1808 浏览
提问于 2025-04-16 23:14

我有一个Python生成器,它会产生大量数据,这样会消耗很多内存。有没有办法检测到这些处理过的数据是否已经被使用这个生成器的代码“消费”掉了?如果是的话,能不能暂停一下,等数据被消费掉再继续?

def multi_grab(urls,proxy=None,ref=None,xpath=False,compress=True,delay=10,pool_size=50,retries=1,http_obj=None):
    if proxy is not None:
        proxy = web.ProxyManager(proxy,delay=delay)
        pool_size = len(pool_size.records)
    work_pool = pool.Pool(pool_size)
    partial_grab = partial(grab,proxy=proxy,post=None,ref=ref,xpath=xpath,compress=compress,include_url=True,retries=retries,http_obj=http_obj)
    for result in work_pool.imap_unordered(partial_grab,urls):
        if result:
            yield result

从这里运行:

if __name__ == '__main__':
    links = set(link for link in grab('http://www.reddit.com',xpath=True).xpath('//a/@href') if link.startswith('http') and 'reddit' not in link)
    print '%s links' % len(links)
    counter = 1
    for url, data in multi_grab(links,pool_size=10):
        print 'got', url, counter, len(data)
        counter += 1

4 个回答

0

我觉得你可能在找 yield 这个功能。可以参考另一个StackOverflow的问题来了解:Python中的"yield"关键字是干什么的?

2

在Python中,生成器的作用是避免在每次循环后留下多余的、不需要的对象。只有当这些对象在别的地方被引用时(比如说被添加到一个列表中),它们才会被保留,这样就会占用额外的内存。确保你没有不必要地保存这些变量。

如果你在处理多线程或多进程的情况,那么你可能需要实现一个队列,这样你可以从中提取数据,并跟踪你正在处理的任务数量。

8

生成器就是用来产生值的。它并不知道这些值被用来做什么。

但是,生成器会不断地暂停,因为调用它的地方在进行其他操作。它不会继续执行,直到调用者要求它提供下一个值。生成器并不是在一个单独的线程中运行。听起来你对生成器的工作原理有些误解。你能分享一些代码吗?

撰写回答