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

作为函数参数的异步函数的Python类型暗示,python,pycharm,python-asyncio,type-hinting,Python,Pycharm,Python Asyncio,Type Hinting,我试图确保函数参数是异步函数。 因此,我正在使用以下代码: 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

我试图确保函数参数是异步函数。 因此,我正在使用以下代码:

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中不再出现这个错误

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

看看这些问题:

(从今天开始打开)-异步键入 (从今天开始打开)-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)
我不能保证他们的意思是正确的,但我的暗示是这样的:

可选
-当然可以是
或其他,在这种情况下:

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

Coroutine[Any,Any,Any]
-这是从OP复制的,非常通用。您建议此
函数可以是
等待
-ed,也可以由
消费者
接收
发送()
-ed,然后由它进行
下一步()
-ed/迭代。很可能是这样,但是

如果只是等待,那么最后一部分可能是:

可等待的[任何]
,如果你真的在等待某件事或

Awaitable[None]
,如果回调没有返回任何内容,而您只希望
等待它

注意:您的
消费者
不是
异步
。它不会真正地等待你的
函数,而是
从它中屈服,或者做一些
循环。运行直到完成()
。创建任务()
,或
。确保未来()

你正在寻找的:

FuncType = Callable[[Any, Any], Coroutine[Any]]
def consumer(function_: FuncType = None):
为什么类型的结构是这样的?如果您声明了一个函数
async
,那么您实际要做的就是用给定的参数将其包装到一个新函数中,该函数将返回一个
Coroutine


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

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

这是一个函数,它接受
Foo
Bar
,并返回
FooBar

如果您通过
test()
进入
消费者
,会发生什么?根据Python3.7
type(test)
function
,而
type(test())
corroutine
,尽管
test
是一个corroutine和pyre检查,在代码中没有发现错误。当我尝试您建议的
functtype
时,mypy似乎同样喜欢使用普通函数作为异步函数。因此,这种类型似乎并不限制您只使用
async def
样式的函数。只有回调本身具有良好的类型提示时,这才有效。具体来说,如果他们定义了他们的返回类型。否则,即使是非异步函数也有返回类型
Any
,mypy会说是针对
Coroutine[Any]
进行类型检查。至少我认为这就是发生的事情。@hwjp是的,当然
Coroutine
只是异步函数的返回类型。因此,如果您的函数没有声明返回类型,它可能会秘密地表现为异步类型。