【问题标题】:Tornado Coroutine fails with 'dict' object not callabaleTornado 协程因 'dict' 对象不可调用而失败
【发布时间】:2022-02-24 12:22:48
【问题描述】:

Python 版本:3.6

我不是 Python 方面的超级专家,我试图使用 Tornado 来实现一个简单的 REST 服务器,并使用非阻塞协程来调用阻塞函数。当我从阻塞函数返回 Json 时,TypeError: 'dict' object is not callable 失败 这是代码

@gen.coroutine
def post(self):
    jsonResponse = yield self.process_request(imageBytes)
    self.write(json.dumps(jsonResponse))

@gen.coroutine
def process_request(self, imageBytes):
    response = yield (executor.submit(self.test_func(), None))
    return response

def test_func(self):
    print('test func')
    time.sleep(1)
    jsonDataSet = {"text": "hello 123"}
    return jsonDataSet

我不确定自己做错了什么,请遵循 Tornado 参考中的示例代码。任何指针都会有帮助吗?

最新: 我转移到异步和等待现在我得到 “'coroutine' 类型的对象不是 JSON 可序列化的”

async def test_func():
    print('test func')
    time.sleep(1)
    jsonDataSet = {"text": "hello 123"}
    return jsonDataSet
    #return "test"
response = await `tornado.ioloop.IOLoop.current().run_in_executor(None, test_func)`

【问题讨论】:

  • 您正在调用 self.test_func() 而不是将其作为可调用对象传递给执行程序。这就是为什么将 dict (´jsonDataSet`) 传递给尝试调用它的执行程序的原因。
  • 已更正,但现在无法识别 test_func
  • 我在类外创建了全局函数,这是同样的错误。 'dict' 对象不可调用

标签: python-asyncio tornado


【解决方案1】:

TypeError: 'dict' 对象不可调用

executor.submit() 需要一个可调用对象,但您已经在调用 test_func 函数。当您调用test_func() 时,实际上是将其返回值(即字典)传递给submit() 函数。

你需要传递这个函数而不调用:

executor.submit(self.test_func, None)

最新:我转移到 async & await 现在我得到“'coroutine' 类型的对象不是 JSON 可序列化的”

run_in_executor 用于在单独的线程中运行普通函数。它不适用于运行协程。

这里发生的事情是run_in_executor 正在调用test_func() 协程,它会自动返回一个等待对象(因为它是一个协程)。

如果您想使用run_in_executor 执行test_func,只需将其设为普通函数即可(不要使用async def)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-06
    • 2011-10-01
    • 2016-07-07
    • 2020-10-10
    • 2020-10-16
    • 2020-09-03
    相关资源
    最近更新 更多