gpt4 book ai didi

python - 无法将等待传递给 asyncio.run_coroutine_threadsafe

转载 作者:太空宇宙 更新时间:2023-11-04 02:18:14 30 4
gpt4 key购买 nike

我观察到 asyncio.run_coroutine_threadsafe 函数不接受一般的可等待对象,我不明白这种限制的原因。观察

import asyncio


async def native_coro():
return


@asyncio.coroutine
def generator_based_coro():
return


class Awaitable:
def __await__(self):
return asyncio.Future()


loop = asyncio.get_event_loop()

asyncio.run_coroutine_threadsafe(native_coro(), loop)
asyncio.run_coroutine_threadsafe(generator_based_coro(), loop)
asyncio.run_coroutine_threadsafe(Awaitable(), loop)

用 Python 3.6.6 运行它会产生

Traceback (most recent call last):
File "awaitable.py", line 24, in <module>
asyncio.run_coroutine_threadsafe(Awaitable(), loop)
File "~/.local/python3.6/lib/python3.6/asyncio/tasks.py", line 714, in run_coroutine_threadsafe
raise TypeError('A coroutine object is required')
TypeError: A coroutine object is required

第 24 行是 asyncio.run_coroutine_threadsafe(Awaitable(), loop)

我知道我可以将我的可等待对象包装在一个定义如下的协程中

awaitable = Awaitable()

async def wrapper():
return await awaitable

asyncio.run_coroutine_threadsafe(wrapper(), loop)

但是我的期望是等待对象将是直接到 run_coroutine_threadsafe 的有效参数。

我的问题是:

  1. 此限制的原因是什么?
  2. 上面定义的 wrapper 函数是否是将可等待对象传递给 run_coroutine_threadsafe 和其他需要 async def 或生成器的 API 的最传统方式-定义协程?

最佳答案

What is the reason for this restriction?

查看 implementation ,原因当然不是技术性的。由于代码已经调用了 ensure_future(而不是 create_task),它会自动工作,并且可以在任何可等待的对象上正确工作。

限制的原因可以在跟踪器上找到。由于 pull request,该功能于 2015 年添加。 .在讨论相关bpo issue提交者明确请求将函数重命名为 ensure_future_threadsafe(与 ensure_future 并行)并接受任何类型的可等待,Yury Selivanov 支持这一立场。然而,Guido 是 against想法:

I'm against that idea. I don't really see a great important future for this method either way: It's just a little bit of glue between the threaded and asyncio worlds, and people will learn how to use it by finding an example.

[...]

But honestly I don't want to encourage flipping back and forth between threads and event loops; I see it as a necessary evil. The name we currently have is fine from the POV of someone coding in the threaded world who wants to hand off something to the asyncio world.

Why would someone in the threaded world have an asyncio.future that they need to wait for? That sounds like they're mixing up the two worlds -- or they should be writing asyncio code instead of threaded code.

还有其他类似的评论,但以上几乎总结了这个论点。

Is the wrapper function defined above the most conventional way to pass an awaitable to run_coroutine_threadsafe and other APIs that demand an async def or generator-defined coroutine?

如果您确实需要协程对象,wrapper 之类的东西无疑是获得协程对象的一种直接且正确的方法。

如果您创建包装器的唯一原因是调用 run_coroutine_threadsafe,但您实际上对结果或返回的 concurrent.futures.Future 不感兴趣通过run_coroutine_threadsafe,你可以通过直接调用call_soon_threadsafe来避免包装:

loop.call_soon_threadsafe(asyncio.ensure_future, awaitable)

关于python - 无法将等待传递给 asyncio.run_coroutine_threadsafe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52140445/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com