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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:35:33