这不是一个大问题,但我只是想知道解决这个问题的方法。 由于我是在 Python 上使用函数注释的新手,所以我对它并不熟悉。我在下面有一个问题。
当你制作一个装饰器并想在上面加注解时,你会怎么做?
例如,如下代码。
def decorator(func: Callable[[*args,**kwargs], <what type should be here?>]) -> <??>:
def new_func(*args, **kwargs):
return func(*args, **kwargs)
return new_func
答案 0 :(得分:0)
使用 Any
作为返回类型并返回另一个返回类型为 Callable
的 Any
。从 PEP 484 和 python standard library 中,Callable
的第一个参数必须是可调用参数的类型,而不是参数本身。因此,您在 *args
中使用 **kwargs
和 Callable
是不被接受的。相反,您必须使用省略号 ...
(允许任意数量的位置和关键字参数类型)。
使用泛型类型 (typing.TypeVar
) 更清晰地表达装饰器函数。通俗地说,泛型就是允许类型作为参数的东西。
从 mypy docs 转述(仅供参考:mypy
是 python
的静态类型检查器包):
装饰器函数可以使用泛型类型来表达。泛型可以
被限制为使用特定类型的子类型的值
关键字参数 bound=...
。一个上限可用于
保留装饰器装饰的包装函数的签名。
因此,您的示例变为:
from typing import Any, Callable, TypeVar, cast
F = TypeVar('F', bound=Callable[..., Any])
def decorator(func: F) -> F:
def new_func(*args, **kwargs):
return func(*args, **kwargs)
return cast(F, new_func)
<块引用>
使用 F
上的绑定,以便在
非功能将被拒绝。此外,包装函数 (new_func
)
未进行类型检查,因为(当前)不支持
使用可变数量的参数指定回调签名
一个特定的类型,所以我们必须在最后转换类型。