我最后一次尝试编写一个接受任何可能的 python 函数并使用
--disallow-any-decorated
标志进行 mypy 检查的装饰器,如下所示:
from typing import Any, Callable, TypeVar
T = TypeVar('T')
def decorator(func: Callable[..., T]) -> Callable[..., T]:
def decorated(*args: Any, **kwargs: Any) -> Any:
print('decorated')
return func(*args, **kwargs)
return decorated
@decorator
def foo() -> int:
print('foo')
return 42
print(foo())
但是仍然失败
Type of decorated function contains type "Any" ("Callable[..., int]")
我做错了什么?我也尝试使用
VarArg
中的 KwArg
和 mypy_extensions
代替 ...
,但没有帮助。
使用 TypeVar 吞掉整个 Callable,而不仅仅是返回类型。然后,您向 MyPy 澄清,修饰函数的类型与原始函数相同,从而无需担心“哦,但这里的返回类型几乎可以是任何类型。”
可能需要在最终返回行上使用强制转换。
FuncT = TypeVar(FuncT, bound=Callable)
def decorator(func: FuncT) -> FuncT:
...
return cast(FuncT, decorated)
不允许在装饰器转换后签名中包含
的函数。Any
...
中的 Callable[..., T]
是一种表示可调用函数采用零个或多个 Any
参数的方式。因此,即使声明本身不包含 Any
,它仍然会解析为包含 Any
的声明。