Python子类add_vertices误调用引发TypeError问题求助
Python面向对象TypeError问题:子类覆盖方法引发的参数缺失
问题重现
实现Graph父类和Bipartite_Graph子类时,执行以下测试代码:
B = Bipartite_Graph() B.add_vertices(['a1','a2'],'A') B.add_vertices(['b1'],'B') B.add_edge('a1','b1')
触发如下错误:
line 36, in add_edge self.add_vertices([vertex_name1, vertex_name2]) TypeError: Bipartite_Graph.add_vertices() missing 1 required positional argument: 'partition'
原代码如下:
class Graph(): def __init__(self): self.num_vertices = 0 self.num_edges = 0 self.vertices = {} def __iter__(self): return iter(self.vertices.values()) def __str__(self) -> str: return f'Graph with {self.num_vertices} vertices and {self.num_edges} edges.' def add_vertices(self, vertex_names): for vertex_name in vertex_names: if vertex_name not in self.vertices.keys(): self.vertices.update({vertex_name: Vertex(vertex_name)}) self.num_vertices += 1 def add_edge(self, vertex_name1, vertex_name2): if vertex_name1 != vertex_name2 and vertex_name1 not in self.vertices[vertex_name2].neighbors: if vertex_name1 or vertex_name2 not in self.vertices.keys(): self.add_vertices([vertex_name1, vertex_name2]) self.num_edges += 1 self.vertices[vertex_name1].add_neighbor(self.vertices[vertex_name2]) self.vertices[vertex_name2].add_neighbor(self.vertices[vertex_name1]) def get_max_degree(self): degrees = [] for vertex in self.vertices.values(): degrees.append(len(vertex.neighbors)) return max(degrees) class Bipartite_Graph(Graph): def __init__(self) -> None: self.partA = [] self.partB = [] super().__init__() def __str__(self) -> str: return f'Bipartite graph with {len(self.partA)} vertices in A, {len(self.partB)} vertices in B and {self.num_edges} edges.' def add_vertices(self, vertex_names, partition): for vertex in vertex_names: if partition == 'A': self.partA.append(vertex) super().add_vertices([vertex]) else: self.partB.append(vertex) super().add_vertices([vertex]) def add_edge(self, vertex_nameA, vertex_nameB): if vertex_nameA not in self.partB and vertex_nameB not in self.partA: super().add_edge(vertex_nameA, vertex_nameB)
问题原因
子类Bipartite_Graph重写了父类Graph的add_vertices方法,新增了必填参数partition。当父类Graph的add_edge方法中调用self.add_vertices时,由于self实际指向子类实例,会执行子类的add_vertices方法,但父类调用时未传入partition参数,因此触发参数缺失错误。
解决方案
方案1:父类中强制调用自身的add_vertices方法
修改父类Graph的add_edge方法,将self.add_vertices改为直接调用父类的方法:
def add_edge(self, vertex_name1, vertex_name2): if vertex_name1 != vertex_name2 and vertex_name1 not in self.vertices[vertex_name2].neighbors: if vertex_name1 or vertex_name2 not in self.vertices.keys(): # 强制调用Graph类的add_vertices,而非子类的实现 Graph.add_vertices(self, [vertex_name1, vertex_name2]) self.num_edges += 1 self.vertices[vertex_name1].add_neighbor(self.vertices[vertex_name2]) self.vertices[vertex_name2].add_neighbor(self.vertices[vertex_name1])
优点:无需修改子类逻辑,直接解决父类调用问题;缺点:父类方法与子类耦合度稍高。
方案2:子类add_vertices设置参数默认值并兼容父类调用
调整子类的add_vertices方法,给partition设置默认值None,并在参数为空时直接调用父类逻辑:
def add_vertices(self, vertex_names, partition=None): if partition is None: # 父类调用时直接执行父类的添加逻辑 super().add_vertices(vertex_names) else: for vertex in vertex_names: if partition == 'A': self.partA.append(vertex) else: self.partB.append(vertex) super().add_vertices([vertex])
优点:保持方法名一致,同时兼容父类和子类的调用场景;缺点:需要额外处理参数为空的分支逻辑。
方案3:子类重命名方法,避免覆盖父类方法
子类不重写父类的add_vertices,而是新增一个专门用于添加分区顶点的方法:
class Bipartite_Graph(Graph): # ... 其他方法保持不变 ... # 移除原add_vertices方法,新增以下方法 def add_vertices_to_partition(self, vertex_names, partition): for vertex in vertex_names: if partition == 'A': self.partA.append(vertex) else: self.partB.append(vertex) self.add_vertices([vertex])
调用时改为:
B = Bipartite_Graph() B.add_vertices_to_partition(['a1','a2'],'A') B.add_vertices_to_partition(['b1'],'B') B.add_edge('a1','b1')
优点:完全避免方法覆盖冲突,逻辑清晰;缺点:需要修改原有的调用代码。
内容的提问来源于stack exchange,提问作者aragornthegrey
相关产品推荐
相关产品推荐

