str*_*ker 5 python asynchronous yield generator tornado
最近,我正在学习《龙卷风简介》,并且遇到了以下代码:
class IndexHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@tornado.gen.engine
def get(self):
query = self.get_argument('q')
client = tornado.httpclient.AsyncHTTPClient()
response = yield tornado.gen.Task(client.fetch,
"http://search.twitter.com/search.json?" + \
urllib.urlencode({"q": query, "result_type": "recent", "rpp": 100}))
body = json.loads(response.body)
[...omitted the following code...]
Run Code Online (Sandbox Code Playgroud)
我曾经学习过,这yield
是将通用函数转换为生成器的关键字,当它以形式使用时,other = yield foo
意味着“屈服foo,并且当向我发送值时,将其他值设置为该值”。所以我在ipython中尝试了以下代码:
In [1]: result = 'init' #set a global variable
In [2]: def test_yield():
...: global result
...: print 'start test...'
...: result = yield 'foo'
...: print 'end test...'
...:
In [3]: t = test_yield()
In [4]: t.next()
start test...
Out[4]: 'foo' #'foo' has been yield to the caller, and blocked
Run Code Online (Sandbox Code Playgroud)
现在,我打印了全局varialbe result
,它仍然引用字符串'init':
In [5]: print result
init
Run Code Online (Sandbox Code Playgroud)
然后我调用了该send()
方法,并向发送了一个新字符串yield
:
In [6]: t.send('new message')
end test...
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
/home/chiyu/<ipython-input-6-b86312ad7d0e> in <module>()
----> 1 t.send('new message')
StopIteration:
Run Code Online (Sandbox Code Playgroud)
如预期的那样,StopIteration
引发了a 并输出字符串“ end test ...”,但是现在全局变量result
已更改:
In [7]: print result
new message
Run Code Online (Sandbox Code Playgroud)
适当地,yield
当我们调用该send()
方法时,该语句接受了字符串,并将新字符串分配给变量结果。
我的问题是:
回到上面显示的代码,根据此逻辑,
response = yield tornado.gen.Task(client.fetch,
"http://search.twitter.com/search.json?" + \
urllib.urlencode({"q": query, "result_type": "recent", "rpp": 100}))
Run Code Online (Sandbox Code Playgroud)
当方法client.fetch
返回时,Task
将创建一个实例并将其创建yield
给调用者,但是response
左侧的变量将无法接收任何内容,因为没有send()
方法被执行。我对此很困惑,徒劳地搜索了。
谢谢您的解释,我将不胜感激!
它的意思是“我放弃对你的控制;当你得到这个 Future 的结果时回来”,因此有点像一个异步解引用操作符。Tornado 通过send
在准备好时返回结果来做出响应。
有关更深入的解释,请参阅http://tornado.readthedocs.org/en/latest/gen.html。
您已经了解了Tornado如何使用生成器来处理异步调用。
我在这里假设client
是tornado.httpclient.AsyncHTTPClient()
;的一个实例;它的fetch()
方法带有回调函数。
的tornado.gen.Task
对象只需要一对参考client.fetch
方法 ; 您当时还没有打电话。您正在Task()
使用该方法引用和一个参数构造一个实例,然后产生该实例。
然后龙卷风将会运行Task
; 在Task
将依次调用client.fetch()
所提供的参数,再加上一个回调函数。在client.fetch()
随后异步运行,并调用回调函数。然后将传递给回调的所有内容记录为Task
结果。
然后将该结果IndexHandler.get()
与发送给生成器send()
,从yield Task()
表达式返回并分配给response
。
换句话说,龙卷风并使用.send()
这里的东西被分配到response
。
归档时间: |
|
查看次数: |
1920 次 |
最近记录: |