3

I know the super() function allows you to call a parent method from a child class. So in this example:

class Exam():
    def __init__(self, a):
        self.a = a
        
    def show(self):
        print("This is from parent method")


class Quiz(Exam):
    def __init__(self, b, a):
        super().__init__(a)
        self.b = b
        
    def show(self):
        print("This is from child method")
        super().show()

q = Quiz('b', 'a')
q.show()

>>> 'This is from child method'
>>> 'This is from parent method'
   

What if I added another method called get_score to both the parent and child class like here:

class Exam():
    def __init__(self, a):
        self.a = a
        
    def show(self):
        print("This is from parent method")
        print (self.get_score())
    
    def get_score(self):
        return self.a
    
    
class Quiz(Exam):
    def __init__(self, b, a):
        super().__init__(a)
        self.b = b
        
    def show(self):
        print("This is from child method")
        super().show()
        print (self.get_score())
    
    def get_score(self):
        return self.b

q = Quiz('b', 'a')
q.show()

>>> 'This is from child method'
>>> 'This is from parent method'
>>> 'b'
>>> 'b'

I can understand why calling super().show() in the child class would return 'b' since I am overwriting the get_score() method.

However, is there a way to maintain the integrity of the parent class so that when I do call super().show()

I get this instead?

>>> 'This is from child method'
>>> 'This is from parent method'
>>> 'a'
>>> 'b'

Sorry in advance if this is bad design. Let me know what other alternatives I can take, even if it means I should the name of the method to avoid this kind of collision.

1 Answer 1

2

Use name-mangling, which will prevent the name-collisions in the subclass :

class Exam():
    def __init__(self, a):
        self.a = a

    def show(self):
        print("This is from parent method")
        print (self.__get_score())

    def __get_score(self):
        return self.a

    get_score = __get_score


class Quiz(Exam):
    def __init__(self, b, a):
        super().__init__(a)
        self.b = b

    def show(self):
        print("This is from child method")
        super().show()
        print (self.__get_score())

    def __get_score(self):
        return self.b

    get_score = __get_score


q = Quiz('b', 'a')
q.show()
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer. I wanted to get you suggestion on regarding whether name mangling is considered a good practice? Or is there any other way the same problem can be addressed?
@AnuragReddy it's sole purpose for existing is to prevent name-collisions in subclasses. The other way is to use another name for the method (which is essentially what name-mangling does). You are overriding the method, can't have it both ways. From this toy example, it's hard to say whether this is bad or not
Thanks a lot for the response. Now its much clear to me.
I suppose I could directly call super().get_score() and get the same result but I wanted to obfuscate some of the technical details and allow the user to just a single method that does most of the heavy lifting. Thank you this works. I selected your answer as the best answer! @juanpa.arrivillaga

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.