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
.