You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现兼具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 김인영

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 14:18:12