Python装饰器类型注解:如何为接收类并返回子类的装饰器添加类型提示
类装饰器的类型提示解决方案
针对你写的类装饰器,正确添加类型提示的方式需要结合TypeVar和Protocol(如果需要限定被装饰类的方法),以下是具体实现:
限定被装饰类必须包含func方法(推荐)
因为你的装饰器中调用了super().func(),提前约束被装饰类具备该方法能避免类型检查报错:
from typing import TypeVar, Type, Protocol # 定义协议,规定类必须有func方法 class HasFunc(Protocol): def func(self) -> None: ... # 绑定协议的TypeVar,确保_Class只能是实现该协议的类 _Class = TypeVar("_Class", bound=HasFunc) def decorator(cls: Type[_Class]) -> Type[_Class]: class _Wrapper(cls): def func(self) -> None: super().func() print("patched!") return _Wrapper
说明
HasFunc协议:明确被装饰类必须实现一个无参数、返回None的func方法,mypy会自动检查被装饰类是否符合要求。Type[_Class]:标注参数cls是_Class类型的类对象,返回值同样是Type[_Class]——因为_Wrapper是cls的子类,完全兼容输入的类类型。
通用类装饰器(无方法约束)
如果不需要提前约束被装饰类的方法(但此时若被装饰类无func方法,mypy会在调用super().func()处报错),可以用通用的TypeVar:
from typing import TypeVar, Type _Class = TypeVar("_Class") def decorator(cls: Type[_Class]) -> Type[_Class]: class _Wrapper(cls): def func(self) -> None: super().func() print("patched!") return _Wrapper
你之前报错的原因
之前用cls: Type[_Class]时mypy报错,大概率是因为缺少Type的导入,或者_Class没有正确绑定类型边界,导致mypy无法识别cls作为合法的类类型。
内容的提问来源于stack exchange,提问作者xis
相关产品推荐
相关产品推荐

