您的位置:

tornado报错BadYieldError("yielded unknown object %r" % (yielded,))怎么办

  发布时间:2025-02-25 08:42:44
该内容介绍了Tornado中出现BadYieldError错误的原因和解决方案,以及具体例子。在协程中使用不支持的对象进行yield操作会触发该错误。解决方法包括确保使用正确的语法和约定、检查yield后的对象类型、正确处理异步操作等。示例代码展示了如何正确使用Tornado避免该错误。

问题原因

tornado出现BadYieldError("yielded unknown object %r" % (yielded,))的原因是在协程(coroutine)中使用了不支持的对象进行yield操作。在tornado中,yield语句用于将控制权让渡给调用协程的函数,并将结果返回给协程。然而,如果yield操作的对象不是tornado支持的类型,就会触发BadYieldError错误。 通常情况下,tornado支持的yield对象包括异步操作(例如Future对象)、tornado.gen模块中的协程以及其他特定的可迭代对象。如果在协程中使用了未知对象进行yield操作,tornado无法正确处理该对象,从而导致BadYieldError错误的出现。

解决方案

Tornado 出现 BadYieldError("yielded unknown object %r" % (yielded,)) 错误通常是因为在使用 Tornado 的协程时,yield 了一个未知类型的对象,导致 Tornado 无法正确处理。要解决这个问题,可以按照以下方法进行: 1. 确保在使用 Tornado 协程时,使用正确的语法和约定。确保在协程内部使用 yield 语句时,yield 的是 Tornado 预期的对象类型,比如 Future、Task 等。 2. 检查代码中的 yield 语句,确保 yield 后面的对象是 Tornado 可以处理的类型,例如异步函数、Future 对象等。 3. 确保在协程中正确处理异步操作,避免在 yield 之后返回不同于 Tornado 预期类型的对象。 4. 可以尝试在 yield 前后加入日志输出,以便更好地追踪错误的根源。 下面是一个示例代码,展示了一个简单的 Tornado 协程,并正确 yield Future 对象以避免 BadYieldError 错误的出现:


import tornado.ioloop
import tornado.web
from tornado.gen import coroutine
from tornado.concurrent import Future

class MainHandler(tornado.web.RequestHandler):
    @coroutine
    def get(self):
        future = Future()

        # 模拟异步操作
        tornado.ioloop.IOLoop.current().add_timeout(tornado.ioloop.IOLoop.current().time() + 1, lambda: future.set_result("Hello, Tornado!"))

        result = yield future  # 正确的 yield Future 对象

        self.write(result)

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

通过以上方法,可以有效地解决 Tornado 出现 BadYieldError 错误的问题。

具体例子

在 Tornado 中出现 BadYieldError("yielded unknown object %r" % (yielded,)) 错误通常是由于在协程中使用了不支持的 yield 语句而导致的。为了正确使用 Tornado,需要确保在协程中只使用支持的 yield 语句。 具体的解决方法是在编写协程时,确保 yield 语句后面跟随的是 Tornado 支持的对象类型,如 Future、Task 或 Awaitable 对象。 下面是一个简单的例子来说明如何正确使用 Tornado 并避免 BadYieldError 错误:


import tornado.ioloop
import tornado.web
import tornado.gen

class MainHandler(tornado.web.RequestHandler):
    @tornado.gen.coroutine
    def get(self):
        # 模拟一个异步操作,返回一个 Future 对象
        future = yield self.async_task()
        result = yield future  # 等待 Future 对象完成
        self.write("Result: " + str(result))

    @tornado.gen.coroutine
    def async_task(self):
        # 模拟一个异步操作,返回一个 Future 对象
        future = tornado.concurrent.Future()
        tornado.ioloop.IOLoop.current().add_timeout(tornado.ioloop.IOLoop.current().time() + 1, lambda: future.set_result("done"))
        raise tornado.gen.Return(future)

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

在上面的例子中,MainHandler 类中的 get 方法和 async_task 方法都被装饰为协程,并使用了 Tornado 提供的支持的 yield 语句,确保不会触发 BadYieldError 错误。