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

