python - 部分异步函数未被检测为异步

标签 python python-asyncio

我有一个函数可以接受常规函数和异步函数(不是协程,而是返回协程的函数)。

它在内部使用 asyncio.iscoroutinefunction() test看看它得到了哪种类型的功能。

最近,当我尝试创建一个部分异步函数时它崩溃了。

在此演示中,ptest 被识别为协程函数,即使它返回协程,即 ptest() 协程。

import asyncio
import functools

async def test(arg): pass
print(asyncio.iscoroutinefunction(test))    # True

ptest = functools.partial(test, None)
print(asyncio.iscoroutinefunction(ptest))   # False!!

print(asyncio.iscoroutine(ptest()))         # True

问题原因很清楚,但解决方案却不清楚。

如何动态创建一个通过测试的部分异步函数?

如何测试包裹在 partial object 中的函数?

任何一个答案都可以解决问题。

最佳答案

使用 Python 版本 < 3.8 你不能让 partial() 对象通过该测试,因为测试要求有一个 __code__ 对象直接附加到传递给 inspect.iscoroutinefunction() 的对象。

您应该改为测试 partial 包装的函数对象,可通过 partial.func attribute 访问:

>>> asyncio.iscoroutinefunction(ptest.func)
True

如果您还需要测试 partial() 对象,则针对 functools.partial 进行测试:

def iscoroutinefunction_or_partial(object):
    while isinstance(object, functools.partial):
        object = object.func
    return inspect.iscoroutinefunction(object)

在 Python 3.8(及更新版本)中,inspect 模块(asyncio.iscoroutinefunction() 委托(delegate))中的相关代码为 updated to handle partial() objects ,您不再需要自己解包 partial() 对象。该实现使用相同的 while isinstance(..., functools.partial) 循环。

关于python - 部分异步函数未被检测为异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52422860/

相关文章:

python - 使用 exec() 动态调用异步函数

python-3.x - async def 和协程,链接是什么

python - 查找值的位置,在数据框中只出现一次

python - 如何禁用 python 枚举中的某些项目,但不删除它们

python - 在具有单个 CPU 的机器上的单个 celery worker 中运行多个进程

Python 请求流异步

Python 分析 - 汇总我的代码之外的函数调用

python - 如何检测用户使用电视马拉松阅读消息?

python - aiohttp 与 aiohttp-devtools 热重载

python-3.x - 内置打印 (stdout) 的异步版本