Tornado @tornado.gen.coroutine 与 yield
在使用 Tornado 的过程中产生了以下疑问:
- 什么时候需要给函数增加
@tornado.gen.coroutine
- 什么时候调用函数需要
yield
@tornado.gen.coroutine
与 yield
是如何工作的
包含 yield
的函数是一个 generator[1]。@gen.coroutine
通过 yield
与 generator 沟通、通过返回 Future
与协程的调用者沟通。
具体沟通情况:
@gen.coroutine
收到从 generator 返回的Future
- "unwraps"
Future
获得结果 - 将结果发送回 generator 以作为
yield
表达式的结果
如何调用协程
上文提到,
@gen.coroutine
通过返回Future
与协程的调用者沟通
所以我们必须 "unwraps" 这个 Future
才能得到结果。
所以在绝大部分情况下,任何调用协程的函数本身必须是一个协程,并且在调用中要使用 yield
。
@gen.coroutine
def good_call():# yield will unwrap the Future returned by divide() and raise# the exception.yield divide(1, 0)
注意,yield
只有在 @gen.coroutine
中才会 "unwraps" 一个 Future
,如果没有 @gen.coroutine
,那么 yield
只会将该函数变为一个而普通的生成器,比如下面两个例子。
- 错误的
import tornado.gen
from tornado.ioloop import IOLoop
from tornado.gen import Return@tornado.gen.coroutine
def call_me():raise Return('result')def f():r = yield call_me()print(r) # tornado.gen.BadYieldError: yielded unknown object <generator object f at 0x104a34320>IOLoop.current().run_sync(f)
错误的原因是:run_sync
会调用 f()
,然后尝试将 f()
的结果转换为 Future
,转换的函数如下:
# env/lib/python2.7/site-packages/tornado/gen.py:1259
def convert_yielded(yielded):"""Convert a yielded object into a `.Future`.The default implementation accepts lists, dictionaries, and Futures.If the `~functools.singledispatch` library is available, this functionmay be extended to support additional types. For example::@convert_yielded.register(asyncio.Future)def _(asyncio_future):return tornado.platform.asyncio.to_tornado_future(asyncio_future).. versionadded:: 4.1"""# Lists and dicts containing YieldPoints were handled earlier.if yielded is None:return momentelif isinstance(yielded, (list, dict)):return multi(yielded)elif is_future(yielded):return yieldedelif isawaitable(yielded):return _wrap_awaitable(yielded)else:raise BadYieldError("yielded unknown object %r" % (yielded,))
由于 f()
返回的是一个 generator
对象,不符合转换的要求,所以报错。如果给 f()
加上 @tornado.gen.coroutine
,那么装饰器会将 f()
返回的结果转换为 Future
,符合 elif is_future(yielded):
,也就能顺利运行。
- 正确的
import tornado.gen
from tornado.ioloop import IOLoop
from tornado.gen import Return@tornado.gen.coroutine
def call_me():raise Return('result')@tornado.gen.coroutine
def f():r = yield call_me()print(r) # resultIOLoop.current().run_sync(f)
总结
- 当调用一个协程时,
@tornado.gen.coroutine
与yield
必须同时出现调用函数中 - 如果只是在协程中执行操作或者直接返回结果,有
@tornado.gen.coroutine
和 return(raise Return)就够了
参考
- https://docs.python.org/2.4/ref/yield.html
- http://www.tornadoweb.org/en/stable/guide/coroutines.html#how-it-works
转载于:https://www.cnblogs.com/jay54520/p/9118621.html
Tornado @tornado.gen.coroutine 与 yield相关推荐
- tornado源码分析(四)之future、gen.coroutine
future是什么 在事件驱动编程模型中,会有很多的事件循环,各事件循环在创建异步事件时可以同时创建一个future对象,并将创建的异步事件与该future对象存储在一起,并将所有传入的callbac ...
- tornado协程(coroutine)原理
tornado中的协程是如何工作的 本文将按以下结构进行组织,说明tornado中协程的执行原理 协程定义 生成器和yield语义 Future对象 ioloop对象 函数装饰器coroutine 总 ...
- tornado协程(coroutine)
tornado中的协程是如何工作的 本文将按以下结构进行组织,说明tornado中协程的执行原理 协程定义 生成器和yield语义 Future对象 ioloop对象 函数装饰器coroutine 总 ...
- 简单总结协程Coroutine及Yield常见用法
原文地址:http://blog.csdn.net/qq_18995513/article/details/51944602 最近学习协程Coroutine,参考了别人的文章和视频教程,感觉协程用法还 ...
- ajax长轮询tornado,Tornado长轮询和WebSocket
Http协议是一种请求响应式协议, 不允许服务端主动向客户端发送信息. 短轮询是一种简单的实现服务端推送消息的解决方案, 客户端以一定间隔自动向服务端发送刷新请求, 服务端返回要推送的消息作为响应. ...
- 实践,用tornado实现自定义协议server
前言 俗话说"光说不练假把式",上一篇文里都只是光看着别人的源码说,貌似有点纸上谈兵的意思. 所以这次写一个简单的,自己定义协议的server. 既可以熟悉Future和corou ...
- Python Web框架Tornado的异步处理代码演示样例
1. What is Tornado Tornado是一个轻量级但高性能的Python web框架,与还有一个流行的Python web框架Django相比.tornado不提供操作数据库的ORM接口 ...
- 自学Python第二十六天- Tornado 框架
自学Python第二十六天- Tornado 框架 安装及基础引用 创建.配置.初始化应用及简单运行服务 创建应用 对 app 进行设置 另一种设置方法 一些其他的配置 关于调试模式 设置路由处理器 ...
- 关于Tornado实现多进程/多线程的理解及参考
方案所用到模块及模块介绍: import tornado.gen tornado.gen 模块是一个基于 python generator 实现的异步编程接口. 通过该模块提供的 coroutine ...
- Tornado 异步协程coroutine原理
协程定义: 协程,又称微线程,纤程.英文名Coroutine. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕 ...
最新文章
- 机器学习之数学基础(一)~maximum likelihood
- Java程序员面试中的多线程问题
- 复习日记-validate表单校验插件/菜单管理dTree
- Golang的值类型和引用类型的范围、存储区域、区别
- JBoss 4.2.x Spring 3 JPA Hibernate教程第2部分
- 电脑有回声_电脑连接麦克风有回音怎么办?麦克风回声的解决方法
- AcWing 180. 排书
- Linux 账户信息显示和实现账户安全
- 正则,bs4 ,xpath 和jsonpath 的匹配规则
- NP、OSPF 缺省路由
- HTML+CSS网页设计视频教程
- WebApi实现验证授权Token,WebApi生成文档等(转)
- elasticsearch APM功能全解 一
- 作为一个渗透测试学习者必知必读的好书推荐
- linux ipcs 命令详解
- Netlogon漏洞复现
- template 的 用法
- 华为ensp的缺省_利用华为ENSP模拟器分析和配置中小型企业网络的综合实验
- 指定SpringBoot内嵌Tomcat的版本,修复(CVE-2021-42340)漏洞
- 对于windows10家庭版无法勾选Hyper-V的问题的解决