Python mypy 注释装饰器 __call__
Python mypy Annotation Decorators __call__
我正在尝试注释作为 class 实现的装饰器,但 mypy 似乎丢失了注释或丢失了类型并认为它是 Any。
我要注释的内容:
class my_decorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
@my_decorator
def func():
return 2
我如何注释它以便 func 在装饰后被检测为返回一个 int?
我意识到上面看起来很简单,我可以将 my_decorator 转换为一个函数,但实际上它是 subclassed 以具有更专业的选项。
您需要将 my_decorator
设为 generic class 并执行如下操作:
from typing import Any, Callable, Generic, TypeVar
T = TypeVar('T')
class my_decorator(Generic[T]):
def __init__(self, func: Callable[..., T]) -> None:
self.func = func
def __call__(self, *args: Any, **kwargs: Any) -> T:
return self.func(*args, **kwargs)
@my_decorator
def func() -> int:
return 2
也就是说,使用 TypeVar 捕获函数的 return 类型,其作用域为 my_decorator
class。当我们在分析 __call__
.
的任何调用时尝试使用它时,这确保绑定到 TypeVar 的值是“可用的”
遗憾的是,无法确保 __call__
的参数与 func()
的参数匹配。因此,如果您尝试执行 func(1, 2, 3)
.
之类的操作,mypy 将不会报告错误
一旦 mypy 添加了对 PEP 612 的支持,这可能会成为可能,这通常会更好地支持键入 decorator-related 代码。
我正在尝试注释作为 class 实现的装饰器,但 mypy 似乎丢失了注释或丢失了类型并认为它是 Any。 我要注释的内容:
class my_decorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
@my_decorator
def func():
return 2
我如何注释它以便 func 在装饰后被检测为返回一个 int? 我意识到上面看起来很简单,我可以将 my_decorator 转换为一个函数,但实际上它是 subclassed 以具有更专业的选项。
您需要将 my_decorator
设为 generic class 并执行如下操作:
from typing import Any, Callable, Generic, TypeVar
T = TypeVar('T')
class my_decorator(Generic[T]):
def __init__(self, func: Callable[..., T]) -> None:
self.func = func
def __call__(self, *args: Any, **kwargs: Any) -> T:
return self.func(*args, **kwargs)
@my_decorator
def func() -> int:
return 2
也就是说,使用 TypeVar 捕获函数的 return 类型,其作用域为 my_decorator
class。当我们在分析 __call__
.
遗憾的是,无法确保 __call__
的参数与 func()
的参数匹配。因此,如果您尝试执行 func(1, 2, 3)
.
一旦 mypy 添加了对 PEP 612 的支持,这可能会成为可能,这通常会更好地支持键入 decorator-related 代码。