gpt4 book ai didi

python - 编写一个同样产生正常值的 Tornado 协程

转载 作者:太空宇宙 更新时间:2023-11-03 11:30:10 24 4
gpt4 key购买 nike

在 Tornado 中,我们可以使用协程装饰器将异步函数巧妙地编写为 Python 生成器,其中每个 yield 语句返回给调度程序,最后的 raise/return 返回一个值给调用者。但是有什么方法可以将一系列值返回给调用者,穿插在异步调用中?

例如我怎样才能打开这个同步功能:

def crawl_site_sync(rooturi):
rootpage = fetch_page_sync(rooturi)
links = extract_links(rootpage)
for link in links:
yield fetch_page_sync(link.uri)

...我可以这样调用它:

for page in crawl_site_sync("http://example.com/page.html"):
show_summary(page)

...进入 Tornado 中看起来相似的异步函数?例如:

@tornado.gen.coroutine
def crawl_site_async(rooturi):
# Yield a future to the scheduler:
rootpage = yield fetch_page_async(rooturi)
links = extract_links(rootpage)
for link in links:
# Yield a future to the scheduler:
sub_page = yield fetch_page_async(link.uri)
# Yield a value to the caller:
really_really_yield sub_page # ???

我该如何调用它?

for page in yield crawl_site_sync("http://example.com/page.html"):
# This won't work, the yield won't return until the entire
# coroutine has finished, and it won't give us an iterable.
show_summary(page)

我可以想办法完成它,但所有这些都涉及到更改调用站点和函数的程度,以至于它完全失去了看起来与同步版本非常相似的异步版本的好处,而且它不再干净地组成。我觉得我必须在这里错过一个技巧。有没有办法同时使用 Python 生成器作为延迟计算值序列作为 Tornado 协程?

最佳答案

我会使用来自 Toro 的队列,这是为协程设计的,可以像这样合作。这是一个简单的例子:

from tornado.ioloop import IOLoop
from tornado import gen
from tornado.httpclient import AsyncHTTPClient
from toro import Queue

q = Queue(maxsize=1)


@gen.coroutine
def consumer():
item = yield q.get()
while item:
print item
item = yield q.get()


@gen.coroutine
def producer():
try:
client = AsyncHTTPClient()
for url in [
'http://tornadoweb.org',
'http://python.org',
'http://readthedocs.org']:
response = yield client.fetch(url)
item = (url, len(response.body))
yield q.put(item)

# Done.
q.put(None)
except Exception:
IOLoop.current().stop()
raise

future = producer()
IOLoop.current().run_sync(consumer, timeout=20)

Toro 的文档中有一个更详细的网络爬虫示例:

https://toro.readthedocs.org/en/stable/examples/web_spider_example.html

关于python - 编写一个同样产生正常值的 Tornado 协程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22408228/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com