Python 异步函数的类型提示作为函数参数

Python type hinting for async function as function argument

我正在尝试确保函数参数是异步函数。 所以我正在玩以下代码:

async def test(*args, **kwargs):
    pass

def consumer(function_: Optional[Coroutine[Any, Any, Any]]=None):
    func = function_

consumer(test)

但是不行。

我在 pyCharm 中进行类型检查时遇到以下错误:

Expected type 'Optional[Coroutine]', got '(args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Coroutine[Any, Any, None]' instead

任何人都可以给我一些解决方法的提示吗?

我帮不了你太多,特别是因为现在(PyCharm 2018.2)这个错误不再在 Pycharm 中出现。

目前,类型提示介于 reflection/introspection 的可靠元数据和接受用户输入的任何内容的美化注释之间。对于普通数据结构,这很棒(我的同事甚至基于类型制作了一个验证框架),但当回调和异步函数发挥作用时,事情会变得更加复杂。

看看这些问题:

https://github.com/python/typing/issues/424(今天开放)- 异步类型 https://github.com/python/mypy/issues/3028(从今天开始)- var-args 可调用类型

我会选择:

from typing import Optional, Coroutine, Any, Callable


async def test(*args, **kwargs):
    return args, kwargs


def consumer(function_: Optional[Callable[..., Coroutine[Any, Any, Any]]] = None):
    func = function_
    return func


consumer(test)

我不保证他们就是这个意思,但我的提示是这样构建的:

Optional - 当然,可以是 None 之类的,在这种情况下:

Callable - 可以用 () 调用的东西,... 代表任何参数,它产生:

Coroutine[Any, Any, Any] - 这是从 OP 复制的,非常笼统。你建议这个 function_ 可能是 await-ed,但也接收由 consumer 编辑的东西 send(),并由它 next()-ed/迭代.很可能是这样,但是...

如果只是 await-ed,那么最后一部分可能是:

Awaitable[Any],如果你真的在等待某事或

Awaitable[None],如果回调没有 return 任何东西,而您只希望 await 它。

注意:您的 consumer 不是 async。它不会真的 await 你的 function_,而是 yield from 它,或者做一些 loop.run_until_complete().create_task(),或 .ensure_future().

您正在寻找:

FuncType = Callable[[Any, Any], Coroutine[Any]]
def consumer(function_: FuncType = None):
    pass  # TODO: do stuff

为什么类型结构是这样的?如果你声明一个函数 async,你实际上做的是用给定的参数将它包装在一个新函数中,returns a Coroutine.


由于这可能与来到这里的某些人有关,因此这是 await可用函数类型的示例:

OnAction = Callable[[Foo, Bar], Awaitable[FooBar]]

这是一个接受FooBar和returns一个FooBar

的函数