如何实现兼具dataclass特性、父类继承且被mypy识别的类装饰器?
解决方法
首先修正你的dataclass导入错误(正确写法是from dataclasses import dataclass而非import dataclass as dc),然后通过泛型类型注解让mypy能正确识别装饰器对类的修改效果。
正确实现代码
from dataclasses import dataclass from typing import TypeVar, Type # 示例父类 class Base: def hello(self) -> None: print("hi") T = TypeVar('T') def my_decorator(cls: Type[T]) -> Type[T & Base]: # 1. 让目标类继承Base cls.__bases__ = (Base,) + cls.__bases__ # 2. 为目标类添加dataclass特性 return dataclass(cls) @my_decorator class HasHelloAndDataclass: a: int
为什么这样能被mypy识别
- 用
TypeVar定义泛型变量T,代表被装饰的原始类,装饰器返回类型Type[T & Base]明确告诉mypy:返回的类同时具备原始类T的所有字段和方法,以及Base类的特性。 - 直接修改原类的
__bases__添加父类,再应用dataclass装饰,避免了动态创建新类导致mypy无法追踪字段的问题。
验证效果
现在mypy可以正确识别:
HasHelloAndDataclass具有__init__(self, a: int) -> None方法- 实例的
a属性类型为int - 实例可以调用
hello()方法
兼容旧Python版本(<3.10)
如果使用Python 3.9及以下,不支持T & Base语法,可以用Union替代:
from typing import Union, TypeVar, Type T = TypeVar('T') def my_decorator(cls: Type[T]) -> Type[Union[T, Base]]: cls.__bases__ = (Base,) + cls.__bases__ return dataclass(cls)
内容的提问来源于stack exchange,提问作者Inyoung Kim 김인영
相关产品推荐
相关产品推荐

