🐍Python 函数与面向对象
Dataclass 与 Enum
面试回答
常见问法
@dataclass比普通类省了哪些样板代码?frozen=True、slots=True、kw_only=True分别干什么?NamedTuple、dataclass、TypedDict、pydantic.BaseModel怎么选?Enum、IntEnum、StrEnum、auto()分别什么场景?
回答
待补充:dataclass 是「数据容器类」的标准答案,Enum 是「有限取值」的标准答案,讲选型时要强调「是否需要验证、是否需要序列化、是否要性能」。
追问
dataclass(frozen=True)为什么能让对象可哈希?__post_init__用来做什么?StrEnum(3.11+)和str + Enum有什么区别?- 为什么
Enum成员不能被继承?
原理展开
@dataclass:自动生成__init__ / __repr__ / __eq__,可选__hash__、__slots__- 不可变:
frozen=True→ 冻结 setattr;结合可哈希,可做 dict key __post_init__:在__init__之后做校验或派生字段field(default_factory=list):避免默认参数可变陷阱NamedTuple:轻量级元组,但不可变、无__post_init__Enum:成员唯一、可迭代、==比身份StrEnum/IntEnum:直接和字符串/整数比较
易错点
- 用
[]作默认值,多实例共享同一个列表(忘了field(default_factory=...)) frozen=True后还在__post_init__里改字段,要用object.__setattr__- 用
dataclass当 API 输入校验,其实应该用 pydantic Enum(1) == 1返回 False(除非用IntEnum)
记忆技巧
- dataclass 四开关:
frozen / slots / kw_only / order - 数据容器选型:简单元组 → NamedTuple,属性对象 → dataclass,外部输入 → pydantic,类型字典 → TypedDict
- Enum 口诀:有限取值全写清,需要字面量用 IntEnum / StrEnum