tornado.gen ——基于生成器的协同程序¶
tornado.gen 实现基于生成器的协同程序。
注解
本模块中的“decorator and generator”方法是本机协程(使用 async def 和 await )在python 3.5中引入。不需要与旧版本的Python兼容的应用程序应该使用本机协程。这个模块的某些部分对于本机协程仍然有用,特别是 multi , sleep , WaitIterator 和 with_timeout . 其中一些功能在 asyncio 也可以使用模块,尽管这两个模块未必100%兼容。
协同程序提供了一种在异步环境中工作比链接回调更简单的方法。使用协程的代码在技术上是异步的,但它是作为单个生成器而不是单独的函数集合编写的。
例如,这里有一个基于协程的处理程序:
class GenAsyncHandler(RequestHandler):
@gen.coroutine
def get(self):
http_client = AsyncHTTPClient()
response = yield http_client.fetch("http://example.com")
do_something_with_response(response)
self.render("template.html")
Tornado中的异步函数返回 Awaitable 或 Future ;生成此对象将返回其结果。
您还可以生成其他可扩展对象的列表或dict,这些对象将同时启动并并行运行;结果列表或dict将在完成后返回:
@gen.coroutine
def get(self):
http_client = AsyncHTTPClient()
response1, response2 = yield [http_client.fetch(url1),
http_client.fetch(url2)]
response_dict = yield dict(response3=http_client.fetch(url3),
response4=http_client.fetch(url4))
response3 = response_dict['response3']
response4 = response_dict['response4']
如果 tornado.platform.twisted 是进口的,也有可能产生 Twisted 的 Deferred 物体。见 convert_yielded 用于扩展此机制的函数。
在 3.2 版更改: 添加了 Dict 支持。
在 4.1 版更改: 增加屈服支撑 asyncio 期货和 通过 singledispatch 的 Twisted Deferreds .
装饰器¶
- tornado.gen.coroutine(func: Callable[[...], Generator[Any, Any, _T]]) Callable[[...], Future[_T]][源代码]¶
- tornado.gen.coroutine(func: Callable[[...], tornado.gen._T]) Callable[[...], Future[_T]]
异步生成器的装饰器。
为了与旧版本的python兼容,协程还可以通过引发特殊的异常来“返回”
Return(value).带有此修饰符的函数返回
Future.警告
当异常发生在协同程序内时,异常信息将存储在
Future对象。您必须检查Future对象,或者异常可能会被代码忽略。这意味着如果从另一个协程调用函数,则使用类似IOLoop.run_sync对于顶级呼叫,或通过Future到IOLoop.add_future.在 6.0 版更改: 这个
callback参数已删除。请改用返回的等待对象。
- exception tornado.gen.Return(value: Optional[Any] = None)[源代码]¶
从返回值的特殊异常
coroutine.如果引发此异常,则将其值参数用作协程的结果:
@gen.coroutine def fetch_json(url): response = yield AsyncHTTPClient().fetch(url) raise gen.Return(json_decode(response.body))
在python 3.3中,不再需要这个异常:
return语句可直接用于返回值(以前yield和return不能在同一函数中组合WITH值)。与RETURN语句类似,value参数是可选的,但从来没有必要
raise gen.Return(). 这个return语句不能与参数一起使用。
效用函数¶
- tornado.gen.with_timeout(timeout: Union[float, datetime.timedelta], future: Yieldable, quiet_exceptions: Union[Type[Exception], Tuple[Type[Exception], ...]] = ())[源代码]¶
包裹甲
Future(或其他可传递对象)超时。加薪
tornado.util.TimeoutError如果输入的未来在之前没有完成timeout,可按允许的任何形式指定。IOLoop.add_timeout(即datetime.timedelta或相对于IOLoop.time)如果包裹
Future在超时后失败,除非异常是包含在quiet_exceptions(可以是异常类型或类型序列),或者asyncio.CancelledError.包裹
Future不会在超时到期时取消,从而允许重复使用。asyncio.wait_for与此函数类似,但它确实取消了包装Future超时。4.0 新版功能.
在 4.1 版更改: 增加了
quiet_exceptions参数和未处理异常的日志记录。在 4.4 版更改: 添加了对除
Future.在 6.0.3 版更改:
asyncio.CancelledError现在总是被认为是“安静”。在 6.2 版更改:
tornado.util.TimeoutError现在是的别名asyncio.TimeoutError。
- tornado.gen.sleep(duration: float) Future[None][源代码]¶
返回A
Future在给定的秒数后解析。当使用时
yield在协程中,这是一个非阻塞的类似物time.sleep(不应在协程中使用,因为它是阻塞的)::yield gen.sleep(0.5)
请注意,单独调用此函数并不起任何作用;必须等待
Future它返回(通常通过屈服)。4.1 新版功能.
- class tornado.gen.WaitIterator(*args: _asyncio.Future, **kwargs: _asyncio.Future)[源代码]¶
提供一个迭代器以在等待的结果完成时生成这些结果。
产生一组这样的等待:
results = yield [awaitable1, awaitable2]暂停连体衣直到两者都停止
awaitable1和awaitable2返回,然后用两个等待的结果重新启动协同程序。如果任何一个waitable引发异常,表达式将引发该异常,所有结果都将丢失。如果您需要尽快获得每个等待的结果,或者如果您需要一些等待的结果,即使其他人产生错误,也可以使用
WaitIterator::wait_iterator = gen.WaitIterator(awaitable1, awaitable2) while not wait_iterator.done(): try: result = yield wait_iterator.next() except Exception as e: print("Error {} from {}".format(e, wait_iterator.current_future)) else: print("Result {} received from {} at {}".format( result, wait_iterator.current_future, wait_iterator.current_index))
因为结果一旦可用就返回迭代器的输出 与输入参数的顺序不同 . 如果需要知道哪个未来产生了当前结果,可以使用这些属性
WaitIterator.current_future或WaitIterator.current_index从输入列表中获取可等待的索引。(如果关键字参数用于WaitIterator,current_index将使用相应的关键字)。在Python 3.5上,
WaitIterator实现异步迭代器协议,因此它可以与async for语句(请注意,在此版本中,如果有任何值引发异常,则整个迭代将中止,而上一个示例可能会继续出现个别错误)::async for result in gen.WaitIterator(future1, future2): print("Result {} received from {} at {}".format( result, wait_iterator.current_future, wait_iterator.current_index))
4.1 新版功能.
在 4.3 版更改: 补充
async for支持python 3.5。
- tornado.gen.multi(Union[List[Yieldable], Dict[Any, Yieldable]], quiet_exceptions: Union[Type[Exception], Tuple[Type[Exception], ...]] = ())[源代码]¶
并行运行多个异步操作。
children可以是列表,也可以是值为可扩展对象的dict。multi()返回一个新的可扩展对象,该对象解析为包含其结果的并行结构。如果children是一个列表,结果是按相同顺序排列的结果列表;如果是一个dict,则结果是具有相同键的dict。也就是说,
results = yield multi(list_of_futures)等于:results = [] for future in list_of_futures: results.append(yield future)
如果有孩子提出异议,
multi()将升起第一个。所有其他类型都将被记录,除非它们属于quiet_exceptions参数。在一个
yield-基于协程,通常不需要直接调用这个函数,因为当生成一个列表或dict时,协程运行程序会自动调用这个函数。但是,有必要await-基于协程,或通过quiet_exceptions参数。此函数在以下名称下可用
multi()和Multi()因为历史原因。取消A
Future返回的multi()不取消其子项。asyncio.gather类似于multi()但它确实取消了它的子项。在 4.2 版更改: 如果多个yieldables失败,则会记录第一个(引发的)之后的任何异常。增加了
quiet_exceptions参数来禁止所选异常类型的日志记录。在 4.3 版更改: 替换了班级
Multi以及功能multi_future具有统一的功能multi. 增加了对Yieldables的支持,而不是YieldPoint和Future.
- tornado.gen.multi_future(Union[List[Yieldable], Dict[Any, Yieldable]], quiet_exceptions: Union[Type[Exception], Tuple[Type[Exception], ...]] = ())[源代码]¶
同时等待多个异步期货。
由于Tornado 6.0,此函数与
multi.4.0 新版功能.
在 4.2 版更改: 中频倍数
Futures失败,将记录第一个(引发的)之后的任何异常。增加了quiet_exceptions参数来禁止所选异常类型的日志记录。4.3 版后已移除: 使用
multi相反。
- tornado.gen.convert_yielded(yielded: Union[None, Awaitable, List[Awaitable], Dict[Any, Awaitable], concurrent.futures._base.Future]) _asyncio.Future[源代码]¶
将生成的对象转换为
Future.默认实现接受列表、字典和预购。这有一个副作用,即启动任何没有自己启动的协同程序,类似于
asyncio.ensure_future.如果
singledispatch库可用,可以扩展此功能以支持其他类型。例如::@convert_yielded.register(asyncio.Future) def _(asyncio_future): return tornado.platform.asyncio.to_tornado_future(asyncio_future)
4.1 新版功能.
- tornado.gen.maybe_future(x: Any) _asyncio.Future[源代码]¶
皈依者
x变成一个Future.如果
x已经是Future,它只是简单地返回;否则它将被包装在新的Future. 这适合用作result = yield gen.maybe_future(f())当你不知道f()返回AFuture或者没有。4.3 版后已移除: 此函数只处理
Futures,而不是其他可移动的对象。而不是maybe_future,检查您期望的非未来结果类型(通常只是None)yield有什么不知道的。
- tornado.gen.moment¶
允许IOLoop运行一次迭代的特殊对象。
这在正常使用中是不需要的,但它可以帮助长期运行的协同程序,这些协同程序可能会产生即时准备好的期货。
用途:
yield gen.moment在本地协程中,相当于
yield gen.moment是await asyncio.sleep(0).4.0 新版功能.
4.5 版后已移除:
yield None(或)yield现在等价于yield gen.moment.