Python dataclass子类初始化出现AttributeError的问题排查
错误原因及修正方案
核心错误点
__init_subclass__方法误用
这个方法是在子类被定义时触发的,而非实例初始化阶段。你在其中尝试操作cls.vertex_list,但vertex_list是Walk的实例属性(每个实例独立拥有的列表),类本身并不具备这个属性,因此定义Path子类时就会抛出AttributeError。这个方法完全不适合用来初始化实例的顶点列表。私有名称修饰问题
代码里的self.__vertex_list是Python的名称修饰语法,会被自动转换为_Walk__vertex_list,导致子类Path无法直接访问该属性,必须使用公共名称self.vertex_list。__repr__方法的错误__repr__中直接使用join(self.__vertex_list)会报错,因为vertex_list存储的是Vertex对象而非字符串,需要先将每个对象转为字符串;同时也要修正私有名称的问题。冻结数据类的设计冲突
Walk被标记为frozen=True,虽然列表本身是可变对象可以调用append,但冻结数据类的设计意图是实例属性不可修改,这会导致逻辑矛盾,建议去掉frozen=True。
修正后的代码
Walk.py
from .Vertex import Vertex from dataclasses import dataclass, field @dataclass # 移除frozen=True,适配add方法的修改需求 class Walk: vertex_list: list[Vertex] = field(default_factory=list) # 删除错误的__init_subclass__方法 def add(self, vertex: Vertex) -> None: self.vertex_list.append(vertex) def __repr__(self) -> str: # 将每个Vertex对象转为字符串后再拼接 return '--'.join(str(v) for v in self.vertex_list)
Path.py
from .Vertex import Vertex from .Walk import Walk from dataclasses import dataclass @dataclass class Path(Walk): def add(self, vertex: Vertex) -> None: # 使用公共名称访问vertex_list,避免私有修饰的访问问题 if vertex not in self.vertex_list: self.vertex_list.append(vertex) # else分支无实际操作,可直接省略
正确使用方式
src = Vertex(...) # 按你的Vertex类定义完成初始化 # 方式1:初始化时传入顶点列表 path = Path(vertex_list=[src]) # 方式2:先初始化空路径再添加顶点 path = Path() path.add(src)
内容的提问来源于stack exchange,提问作者amkhrjee
相关产品推荐
相关产品推荐

