python - Python mypy 注释装饰器 __call__
问题描述
我正在尝试对作为类实现的装饰器进行注释,但 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 转换为一个函数,但实际上它是子类化的,具有更专业的选项。
解决方案
您将需要创建my_decorator
一个通用类并执行以下操作:
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 捕获函数的返回类型,该类型的范围仅限于您的my_decorator
类。这确保了绑定到 TypeVar 的值在我们分析任何__call__
.
不幸的是,无法确保 的参数__call__
与 的参数匹配func()
。因此,如果您尝试执行类似func(1, 2, 3)
.
一旦 mypy 添加了对PEP 612的支持,这可能会成为可能,这通常会更好地支持键入与装饰器相关的代码。
推荐阅读
- javascript - 条件关闭标签 ReactJS
- python - 许多 nltk 包方法/工具都不起作用
- sql-server - to_sql 未更新 ms 服务器中的表
- julia - 嵌套在 for 循环中的 if 块的 Julia 变量的范围
- c# - 将datagridview的列保存在List中
- python - 将从远程存储库获取的 python 包传递给 spark 提交/shell
- bash - .gz 文件日志中 txt 列表中的大 grep
- angularjs - 意外请求:GET 后跟 [$rootScope:inprog] $digest 已经在进行中。Angularjs 和 Karma
- r - 识别、分组数据框 (R) 中的唯一条目
- python - 两个 AEM 环境中的节点权限比较