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

Python多继承调用子类方法出现AttributeError问题求助

解决Python多继承中访问父类私有属性的AttributeError问题

问题根源

你遇到的AttributeError核心原因是Python的名称修饰机制:父类中用双下划线__开头的属性(比如__roll、__marks1、__activemarks)会被Python自动重命名为_类名__属性名(例如_Student_Marks__roll),子类直接通过self.__roll访问时,找不到对应的属性,因为名称已经被修改了。

另外,Result类__init__里的super().getActiveMarks()存在逻辑问题:多继承中super()按MRO(方法解析顺序)查找下一个类,Result的MRO顺序是Result → Student_Marks → Cocurricular_Marks → object,所以super().getActiveMarks()会尝试在Student_Marks中找该方法,显然找不到——不过你后续手动调用了res.getActiveMarks(),所以这部分暂时没触发报错,但初始化逻辑是不严谨的。

解决方案

方案1:将私有属性改为受保护属性(单下划线)

把父类中双下划线开头的属性改成单下划线_开头,这样子类可以正常访问,同时也能暗示外部代码不要直接修改这些属性。

方案2:给父类添加getter方法

如果想保留双下划线的私有属性,可以在父类中添加获取属性的方法(比如get_roll()、get_total_marks()),子类通过这些方法获取属性值。

这里用方案1修改代码,更简洁直观:

修改后的完整代码

class Student_Marks:
    def __init__(self):
        # 改为单下划线的受保护属性
        self._roll: int
        self._marks1: int
        self._marks2: int
    
    def getMarks(self):
        self._roll = int(input("Enter Roll No: "))
        self._marks1, self._marks2 = map(int, input("Enter Marks: ").split())
        return self._roll, self._marks1, self._marks2


class Cocurricular_Marks:
    def __init__(self):
        # 改为单下划线的受保护属性
        self._activemarks: int
    
    def getActiveMarks(self):
        self._activemarks = int(input("Enter Co Curricular Activities Marks: "))
        return self._activemarks


class Result(Student_Marks, Cocurricular_Marks):
    def __init__(self):
        # 显式初始化两个父类
        Student_Marks.__init__(self)
        Cocurricular_Marks.__init__(self)

    def display(self):
        # 用修改后的受保护属性计算并输出
        total = self._marks1 + self._marks2 + self._activemarks
        avg  = total / 3

        print("Roll No: ", self._roll)
        print("Total Marks: ", total)
        print("Average Marks: ", avg )


# 执行逻辑
res = Result()
res.getMarks()
res.getActiveMarks()
res.display()

补充说明

如果想通过super()处理多继承初始化,可以修改Result的__init__如下:

def __init__(self):
    super().__init__()
    super(Student_Marks, self).__init__()

这里super(Student_Marks, self).__init__()会跳过Student_Marks,直接调用MRO链中后续的Cocurricular_Marks类的初始化方法。

内容的提问来源于stack exchange,提问作者Tshihab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 13:11:14