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
相关产品推荐
相关产品推荐

