- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在 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/
在我的设置中,我试图有一个界面 Table继承自 Map (因为它主要用作 map 的包装器)。两个类继承自 Table - 本地和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。
Rust Nomicon 有 an entire section on variance除了关于 Box 的这一小节,我或多或少地理解了这一点和 Vec在 T 上(共同)变体. Box and Vec
我是一名优秀的程序员,十分优秀!