python - tornado 使用 AsyncHTTPClient 和 gen 请求 url,使用 raise gen.Return 获取异常

标签 python tornado

刚接触tornado,所以跟着tornado的指导练习,当我开始使用Coroutines的时候,例子是这样说的: 从 Tornado 导入生成

@gen.coroutine
def fetch_coroutine(url):
    http_client = AsyncHTTPClient()
    response = yield http_client.fetch(url)
    # In Python versions prior to 3.3, returning a value from
    # a generator is not allowed and you must use
    #   raise gen.Return(response.body)
    # instead.
    return response.body

当我运行这个测试时,它引发了 SyntaxError 'return' with argument inside generator,所以我取消了建议的注释,如下所示: 导入 tornado.httpserver 进口 Tornado .ioloop 导入 tornado.options 导入 tornado.web

from tornado.options import define, options

define("port", default=8888, help="run on the given port", type=int)
from tornado import gen
from tornado.httpclient import AsyncHTTPClient

@gen.coroutine
def fetch_coroutine(url):
    http_client = AsyncHTTPClient()
    response = yield http_client.fetch(url)
    #return response.body
    raise gen.Return(response.body)

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")
        data = fetch_coroutine(url = "http://www.baidu.com")
        self.write(data)
        print data


def main():
    tornado.options.parse_command_line()
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()


if __name__ == "__main__":
    main()

但它会引发这样的异常:

[E 140925 17:35:53 web:1407] Uncaught exception GET / (::1)
    HTTPServerRequest(protocol='http', host='localhost:8888', method='GET', uri='/', version='HTTP/1.1', remote_ip='::1', headers={'Accept-Language': 'zh-TW,zh;q=0.8,zh-CN;q=0.6,en;q=0.4', 'Accept-Encoding': 'gzip,deflate,sdch', 'Host': 'localhost:8888', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36', 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', 'If-None-Match': '"e02aa1b106d5c7c6a98def2b13005d5b84fd8dc8"'})
    Traceback (most recent call last):
      File "/Library/Python/2.7/site-packages/tornado-4.0.2-py2.7-macosx-10.9-intel.egg/tornado/web.py", line 1332, in _execute
        result = method(*self.path_args, **self.path_kwargs)
      File "helloworld.py", line 39, in get
        self.write(data)
      File "/Library/Python/2.7/site-packages/tornado-4.0.2-py2.7-macosx-10.9-intel.egg/tornado/web.py", line 656, in write
        raise TypeError("write() only accepts bytes, unicode, and dict objects")
    TypeError: write() only accepts bytes, unicode, and dict objects
[E 140925 17:35:53 web:1811] 500 GET / (::1) 3.94ms

最佳答案

文档非常similar example :

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")

总结:

  • 在 python 2.x 中你不能返回 block 内的东西,用 @gen.coroutine 装饰,只允许单个 return
  • 在 python 2.x 中,如果你需要在 @gen.coroutine block 中返回一些东西,那么使用 raise gen.Return,正如你正确理解的那样
  • 您不需要在get 方法中返回任何东西来响应一些数据给客户端。您需要为它编写一些东西(在上面的示例中,它是通过调用 self.render 完成的)。

所以,替换这段代码

        do_something_with_response(response)
        self.render("template.html")

用这个:

        self.write(response.body)
        self.finish()

self.finish()将完成响应,结束 HTTP 请求。它在 self.render 方法中自动调用。

最终请求处理程序:

from tornado import gen
from tornado.web import RequestHandler
from tornado.httpclient import AsyncHTTPClient


class GenAsyncHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        http_client = AsyncHTTPClient()
        response = yield http_client.fetch("http://google.com")
        self.write(response.body)
        self.finish()

关于python - tornado 使用 AsyncHTTPClient 和 gen 请求 url,使用 raise gen.Return 获取异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26035303/

相关文章:

Python从内网获取客户端windows用户

html - css 文件显示在 chrome 资源中,但仅在我编辑后才有效

node.js - 关注者的实时新闻源 - 哪些工具和语言?

python - Tornado 在执行器中运行和定义异步方法之间的区别

Python:对于列表中的每2项?

python - Pytorch (1.0) 中类似外观操作的不同 `grad_fn`

python - Django 根据 url 请求预填写表单下拉框

python - 将字典转换为列表

javascript - 在后台上传 Tornado 的html文件中,如何获取成功消息?

python - Pywinauto type_keys() 省略字符串中的 "%"