我试图确保函数参数是异步函数。 所以我正在使用以下代码:
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
任何人都可以给我一些如何解决这个问题的提示吗?
您正在寻找:
FuncType = Callable[[Any, Any], Awaitable[Any]]
def consumer(function_: FuncType = None):
pass # TODO: do stuff
为什么类型是这样的结构?如果您声明一个函数
async
,您实际上所做的是将其包装在具有给定参数的新函数中,该函数返回一个 Coroutine
。
由于这可能与某些来到这里的人相关,因此这是一个具有 in 和 out 类型的
await
可用函数类型的示例:
OnAction = Callable[[Foo, Bar], Awaitable[FooBar]]
这是一个接受
Foo
、Bar
并返回 FooBar
的函数
我帮不了你太多,特别是因为现在(PyCharm 2018.2)这个错误不再在 Pycharm 中出现。
目前,类型提示介于用于反射/内省的可靠元数据和接受用户输入的任何内容的美化注释之间。对于普通数据结构来说,这很棒(我的同事甚至制作了一个基于打字的验证框架),但事情变得更多当回调和异步函数发挥作用时会变得复杂。
看看这些问题:
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
编辑,但也会收到 send()
的 consumer
编辑内容,并被 next()
编辑/迭代。情况很可能是这样,但是...
如果只是
await
编辑,那么最后一部分可能是:
Awaitable[Any]
,如果你真的在等待某事或
Awaitable[None]
,如果回调没有返回任何内容,而你只希望await
它。
注意:您的
consumer
不是 async
。它不会真正await
你的function_
,但要么yield from
它,或者做一些loop.run_until_complete()
或.create_task()
,或.ensure_future()
。