【问题标题】:Detect any function created with async def检测使用 async def 创建的任何函数
【发布时间】:2019-07-10 12:25:19
【问题描述】:

我对 Python 3.6+ 中的以下行为感到困惑:

>>> def f1(): pass
>>> def f2(): yield
>>> async def f3(): pass
>>> async def f4(): yield
>>> inspect.isfunction(f1)
True
>>> inspect.isfunction(f2)
True
>>> inspect.iscoroutinefunction(f3)
True
>>> inspect.iscoroutinefunction(f4)
False

同步函数和生成器函数都被检查视为“函数”,但异步生成器函数不被视为“协程函数”。 这似乎与documentation相反

inspect.iscoroutinefunction(object)

如果对象是协程函数(使用 async def 语法定义的函数),则返回 true。

有没有比同时检查iscoroutinefunctionisasyncgenfunction 更好的方法来检测一个函数是否是用async 定义的,包括生成器函数?

这可能是因为异步生成器只出现在 3.6 中,但仍然令人费解。

【问题讨论】:

    标签: python python-3.6 python-asyncio python-3.7 coroutine


    【解决方案1】:

    异步生成器本身不是协程,不能awaited:

    >>> loop.run_until_complete(f4())
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/haugh/.pyenv/versions/3.6.6/lib/python3.6/asyncio/base_events.py", line 447, in run_until_complete
        future = tasks.ensure_future(future, loop=self)
      File "/home/haugh/.pyenv/versions/3.6.6/lib/python3.6/asyncio/tasks.py", line 526, in ensure_future
        raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
    TypeError: An asyncio.Future, a coroutine or an awaitable is required
    

    我认为您已经确定了检查 async 是否用于定义函数的最佳方法:

    def async_used(func):
        return inspect.iscoroutinefunction(func) or inspect.isasyncgenfunction(func)
    

    【讨论】:

    • 谢谢,这就解释了为什么iscoroutinefunctionf4 上返回False。我认为虽然它的文档应该在引入异步生成器后在 3.6 中更新......
    猜你喜欢
    • 1970-01-01
    • 2017-05-06
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2020-07-26
    相关资源
    最近更新 更多