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

Python dataclass自定义__repr__包含__post_init__生成变量且忽略repr=False字段

解决方案

你可以通过一个可复用的Mixin基类实现所有需求,不用每个dataclass重复写逻辑,代码如下:

from dataclasses import is_dataclass, dataclass, field
import utils

class DataclassFullReprMixin:
    def __repr__(self, nested: bool = False) -> str:
        # 被外层dataclass调用repr时直接返回简写格式
        if nested:
            return f"{self.__class__.__qualname__}(...)"
        
        show_items = []
        for attr_name, attr_value in self.__dict__.items():
            # 过滤标记了repr=False的预定义字段
            if attr_name in self.__dataclass_fields__ and not self.__dataclass_fields__[attr_name].repr:
                continue
            # 处理嵌套dataclass,触发简写输出
            if is_dataclass(attr_value) and not isinstance(attr_value, type):
                value_repr = attr_value.__repr__(nested=True)
            else:
                value_repr = repr(attr_value)
            show_items.append(f"{attr_name}={value_repr}")
        
        return f"{self.__class__.__qualname__}({', '.join(show_items)})"

给你自定义的dataclass继承这个Mixin即可:

@dataclass
class Bar(DataclassFullReprMixin):
    _data: dict = field(repr=False)
    bar: int = 0

    def __post_init__(self):
        """更多嵌套dataclass逻辑"""

@dataclass
class Foo(DataclassFullReprMixin):
    _data: dict = field(repr=False)
    foo: int = 0

    def __post_init__(self):
        # 注意你原代码这里漏了self,应该取实例的_data属性
        self.bar = Bar(**utils.clean(self._data, 'bar'))

效果验证

# 实例化后测试输出
print(foo)
# 输出符合预期:Foo(foo=0, bar=Bar(...))
print(foo.bar)
# 输出符合预期:Bar(bar=0)

额外适配说明

  • 所有动态添加到实例的属性(非预定义dataclass字段)默认都会展示,完全匹配遍历__dict__的需求
  • 只要嵌套的dataclass都继承该Mixin,任意层级的嵌套对象都会在外层输出时显示为类名(...),单独打印时显示完整内容
  • 如果需要调整嵌套展示的深度(比如允许2层以内显示完整内容),把nested参数改为数字类型的递归深度,增加阈值判断即可。

内容的提问来源于stack exchange,提问作者duhby

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:27:03