Ответ 1
Как отметил Лутц Хорн, декоратор tornado.coroutine
требует, чтобы вы приводили только объекты Future
или определенные контейнеры, содержащие объекты Future
. Поэтому попытка получить str
вызовет ошибку. Я думаю, что фрагмент, который вам не хватает, заключается в том, что любое место внутри сопрограммы, в которой вы хотите вызвать yield something()
, something
, должно быть либо сопроводительным, либо возвращать Future
. Например, вы можете исправить свой пример следующим образом:
from tornado.gen import Return
class HelloHandler(RequestHandler):
@gen.coroutine
def get(self):
x = yield self.do_test()
self.render('hello.html')
@gen.coroutine
def do_test(self):
raise Return('test')
# return 'test' # Python 3.3+
Или даже это (хотя обычно вы не должны этого делать):
class HelloHandler(RequestHandler):
@gen.coroutine
def get(self):
x = yield self.do_test()
self.render('hello.html')
def do_test(self):
fut = Future()
fut.set_result("test")
return fut
Конечно, это надуманные примеры; так как мы фактически не делаем асинхронного в do_test
, нет никаких причин сделать его сопрограммой. Обычно вы будете делать какие-то асинхронные операции ввода-вывода. Например:
class HelloHandler(RequestHandler):
@gen.coroutine
def get(self):
x = yield self.do_test()
self.render('hello.html')
@gen.coroutine
def do_test(self):
http_client = AsyncHTTPClient()
out = yield http_client.fetch("someurl.com") # fetch is a coroutine
raise Return(out.body)
# return out.body # Python 3.3+