竜巻コルーチンを学習しようとしていますが、以下のコードを使用するとエラーが発生します。
Traceback (most recent call last):
File "D:\projekty\tornado\env\lib\site-packages\tornado\web.py", line 1334, in _execute
result = yield result
File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 628, in run
value = future.result()
File "D:\projekty\tornado\env\lib\site-packages\tornado\concurrent.py", line 109, in result
raise_exc_info(self._exc_info)
File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 631, in run
yielded = self.gen.throw(*sys.exc_info())
File "index.py", line 20, in get
x = yield 'test'
File "D:\projekty\tornado\env\lib\site-packages\tornado\gen.py", line 628, in run
value = future.result()
File "D:\projekty\tornado\env\lib\site-packages\tornado\concurrent.py", line 111, in result
raise self._exception
BadYieldError: yielded unknown object 'test'
コード:
from tornado.ioloop import IOLoop
from tornado.web import RequestHandler, Application, url
from tornado import gen
class HelloHandler(RequestHandler):
@gen.coroutine
def get(self):
x = yield 'test'
self.render('hello.html')
def make_app():
return Application(
[url(r"/", HelloHandler)],
debug = True
)
def main():
app = make_app()
app.listen(8888)
IOLoop.instance().start()
main()
Lutz Hornが指摘したように、_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
_では実際には非同期を実行していないため、コルーチンにする理由はありません。通常、そこで何らかの非同期I/Oを実行します。例えば:
_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+
_
ドキュメントから :
Tornadoのほとんどの非同期関数は、
Future
;を返します。このオブジェクトを生成すると、その結果が返されます。
yield a list or dict of Futures
、これは同時に開始され、並行して実行されます。結果のリストまたはdictは、すべて終了したときに返されます。
文字列"test"
はFuture
ではありません。 1つを譲ってみてください。