Ich bin ziemlich neu in der Programmierung mit Coroutinen und ich versuche, eine Datenbank-Schnittstelle für eine benutzerdefinierte Datenbank für einen Tornado-Webserver mit Python 2.7.10 zu erstellen. Allerdings bekomme ich immer eine BadYieldError
. Ich fühle, dass dies ist wahrscheinlich nicht ich verstehe, wie tornado.gen.coroutine
mit Pythons yield
vollständig zu verwenden. Ich denke, dass etwas daran falsch ist, wie ich eine Zukunft ergebe.Python BadYieldError beim Rendern Future
Dies ist mein Code, der weiterhin fehlschlägt, wobei die testGet
-Funktion in Zeile 15 eine Simulation eines fremden Datenbankzugriffs ist.
from tornado import gen
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
@gen.coroutine
def get(self):
response = "Hello, world"
response = yield db_interface("default", "user_query")
self.write(str(response))
# meant to demonstrate
def testGet(query):
gen.sleep(2)
response = query
return response
@gen.coroutine
def db_interface(db, key):
print str(db)
d = yield testGet(key)
raise gen.Return(d)
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(8889)
tornado.ioloop.IOLoop.current().start()
Ausgang:
default
ERROR:tornado.application:Uncaught exception GET/(127.0.0.1)
HTTPServerRequest(protocol='http', host='127.0.0.1:8889', method='GET', uri='/', version='HTTP/1.1', remote_ip='127.0.0.1', headers={'Accept-Language': 'en-CA,en;q=0.8,fr;q=0.6', 'Accept-Encoding': 'gzip, deflate, sdch', 'Host': '127.0.0.1:8889', '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_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36', 'Dnt': '1', 'Connection': 'keep-alive', 'Cookie': 'ui-auth-127.0.0.1%3A8091=4f1301ef98f1b6fbd80ad059cd5aa2dc', 'Cache-Control': 'max-age=0', 'Upgrade-Insecure-Requests': '1'})
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/tornado/web.py", line 1415, in _execute
result = yield result
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 870, in run
value = future.result()
File "/usr/local/lib/python2.7/site-packages/tornado/concurrent.py", line 215, in result
raise_exc_info(self._exc_info)
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 876, in run
yielded = self.gen.throw(*exc_info)
File "test.py", line 12, in get
response = yield db_interface("default", "user_query")
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 870, in run
value = future.result()
File "/usr/local/lib/python2.7/site-packages/tornado/concurrent.py", line 215, in result
raise_exc_info(self._exc_info)
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 876, in run
yielded = self.gen.throw(*exc_info)
File "test.py", line 26, in db_interface
d = yield testGet(key)
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 870, in run
value = future.result()
File "/usr/local/lib/python2.7/site-packages/tornado/concurrent.py", line 215, in result
raise_exc_info(self._exc_info)
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 956, in handle_yield
self.future = convert_yielded(yielded)
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 1026, in convert_yielded
raise BadYieldError("yielded unknown object %r" % (yielded,))
BadYieldError: yielded unknown object 'user_query'
ERROR:tornado.access:500 GET/(127.0.0.1) 2011.67ms
Ich habe versucht, zu suchen, wie dies auf Tornado's official documentation richtig zu machen und auf this blog, aber ich glaube nicht, ich habe in der Lage gewesen, was vollständig zu erfassen Sie sagen, wie man Koroutinen benutzt.
Gut 'testGet' wäre ein Datenbankaufruf, keine Funktion, also kann ich es nicht in eine Coroutine verwandeln. Kann ich irgendwie von einer Funktion, die nachgibt, nachgeben? Und wenn ja, ist das eine schlechte Idee? – goatandsheep
Ich gab zwei Optionen in der Antwort: Konvertiere zu Coroutine oder lasse die 'Ausbeute' von' d = yield testGet (key) 'fallen. Willst du sagen, keine Option Arbeit? – Louis
Es ist mir nicht möglich, 'testGet' in eine Coroutine zu verwandeln, da es sich nicht um eine Funktion handelt, sondern um eine Darstellung eines fremden Anrufs, den ich zu Demonstrationszwecken verwende. Der zweite funktioniert, aber warum? Ist es nicht möglich, eine Zukunft, die eine Zukunft darstellt, auszugeben? Wenn ja, was habe ich falsch gemacht, dass Ihre Lösung besser ist? – goatandsheep