Search code examples
python-3.xsupersuperclassintrospection

Why doesn't super().__class__.__name__ return the name of my base class?


I have a base class A that I inherit from to create class B. If I call the name dunder on the class instance, I get the name of the class. if I call the name dunder on the instance's base class, I get the name of the base class. This makes sense so far. However, if call the name dunder on the instance' super(), I don't get the name of the base class and I'm not sure why. To make matters more confusing, If I call the name dunder on the supers()'s base class, I get the correct name for the base's base class object.

class A:
    pass


class B(A):
    def __init__(self):
        self.inherited_class_name = self.__class__.__name__
        self.base_class_name = self.__class__.__bases__[0].__name__
        self.should_return_base_class_name = super().__class__.__name__
        self.base_class_base_class = super().__class__.__bases__[0].__name__


if __name__ == '__main__':
    b = B()
    print(b.inherited_class_name)
    print(b.base_class_name)
    print(b.should_return_base_class_name)  # Why does this return "super" instead of "A"?
    print(b.base_class_base_class)  # Especially when this one works...

prints out

B
A
super 
object

I don't understand why "super" is returned from my should_return_base_class_name call.


Solution

  • This is because super is in fact a distinct class that abstracts away your base class. Super is not actually the base class. When you do super() you are getting an instance of the super class, not an instance of your base class.
    If you try print(super()) in your example you will get <super: <class 'B'>, <B object>>