Search code examples
python-3.xoopinheritancemultiple-inheritance

AttributeError Problem with Multiple inheritance in python


I wanted to calculate the Total and Average Marks of a student with multiple inheritances in python. But whenever I create an object for my child class it gives me access to all the methods of parent classes but shows an AttributeError when I call the method of the child class. I tried to use the super() function but the result is the same.

I just paste my code below. Can you suggest to me a solution to that?

class Student_Marks:
    def __init__(self):
        # initializing variables
        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):
        super().getMarks()
        super().getActiveMarks()

    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 )


# creating Objects
res = Result()

res.getMarks()

res.getActiveMarks()

res.display()      # I got problem here

Solution

  • You're prepending the attributes with two underscores in the classes, this mangles the name of the attribute (see the documentation on Private Variables).

    For instance, Student_Marks's __roll will be mangled to _Student_Marks__roll as you exit getMarks.

    Hence Result.display() not being able to access self.__marks1, but it can access it as self._Student_Marks__marks1.

    See the following minimal example.

    class K:
        __a = 1
    
    class KK(K):
        pass
    
    k = K()
    k.__a  # AttributeError: 'K' object has no attribute '__a'
    k._K__a  # 1
    
    kk = KK()
    kk._K__a  # 1