【问题标题】:The right way to type hint a Coroutine function?键入提示协程函数的正确方法?
【发布时间】:2023-02-14 00:31:28
【问题描述】:

我无法理解提示 Coroutine 的类型。据我了解,当我们这样声明一个函数时:

async def some_function(arg1: int, arg2: str) -> list:
    ...

我们有效地声明一个函数,该函数返回一个协程,在等待时返回一个列表。因此,输入提示的方式是:

f: Callable[[int, str], Coroutine[???]] = some_function

但是 Coroutine 泛型类型有 3 个参数!如果我们转到typing.py 文件,我们可以看到它:

...
Coroutine = _alias(collections.abc.Coroutine, 3)
...

还有Awaitable类型,逻辑上应该是 Coroutine 的父级,只有一个通用参数(我想是返回类型):

...
Awaitable = _alias(collections.abc.Awaitable, 1)
...

因此,以这种方式键入提示函数可能或多或少是正确的:

f: Callable[[int, str], Awaitable[list]] = some_function

或者是吗?

所以,基本上,问题是:

  1. 在类型提示 async def 函数的情况下,可以使用 Awaitable 而不是 Coroutine 吗?
  2. Coroutine 泛型类型的正确参数是什么?它的用例是什么?

【问题讨论】:

    标签: python python-asyncio coroutine type-hinting


    【解决方案1】:

    作为docs状态:

    Coroutine对象和CoroutineABC的实例都是AwaitableABC的实例。

    对于 Coroutine 类型:

    collections.abc.Coroutine 的通用版本。类型变量的方差和顺序对应Generator

    Generator 又具有签名 Generator[YieldType, SendType, ReturnType]。因此,如果您想保留该类型信息,请使用 Coroutine,否则 Awaitable 就足够了。

    【讨论】:

      【解决方案2】:

      Coroutine 类型采用与 Generator 类型相同的签名:

      Generator[YieldType, SendType, ReturnType]

      由于对协同程序的未等待调用的结果是可等待的(它可以在 await 表达式中使用),因此可以使用以下类型提示:

      Awaitable[ReturnType]

      例子:

      async def some_function(arg1: int, arg2: str) -> List[str]:
          return ['foo']
      
      coro: Awaitable[List[str]] = some_function(1, 'bar')
      result = await coro
      print(result)
      # prints ['foo']
      

      但是,对于协程的类型提示,我发现它们中的任何一个都没有用处。 相反,我选择类似于您在上一个示例中所说的内容:

      def return_coro() -> Callable[[int, str], Awaitable[List[str]]]:
          async def some_function(arg1: int, arg2: str) -> List[str]:
              return ['foo']
          return some_function
      

      请注意,如果您尝试将其传递给明确需要协程的函数(例如 asyncio.run()),mypy 会感到不安。

      【讨论】:

        猜你喜欢
        • 2019-05-28
        • 2020-11-17
        • 1970-01-01
        • 2019-03-25
        • 2020-03-01
        • 2020-06-24
        • 2018-04-17
        • 1970-01-01
        • 2020-07-28
        相关资源
        最近更新 更多