John S
John S

Reputation: 101

python: why does `type(super())` return <class 'super'>?

A short inheritance example:

class Person:
    def __init__(self, fname, lname):
        self.firstname = fname
        self.lastname = lname
 
class Student(Person):
    def __init__(self, fname, lname):
        super().__init__(fname, lname) 
        print(type(super()))

Now entering Student("test", "name") will result in <class 'super'> being printed to the console. I'm not familiar with this format. When I do type(int) I see the type as type, not as <class 'int'>. Can someone explain what is going on here?

Upvotes: 0

Views: 177

Answers (1)

Amadan
Amadan

Reputation: 198426

If you take a look at the docs,

Return a proxy object that delegates method calls to a parent or sibling class of type.

This proxy object is of type super; assuming super_object = super(), then type(super_object) returns a type object that describes the class to which all super objects belong to. Just like type(0) returns a type object that describes integers. <class 'int'> is how this type object prints itself. Fun fact: you already know this object.

>>> int
<class 'int'>
>>> type(0)
<class 'int'>
>>> type(0) == int
True

Note that in Python, constructor for a class is the type object itself. So when you write int(), you are constructing a new object of type int, just like when you write Student("test", "name"), you are constructing a new object of type Student. And so it is with super as well:

>>> type(super()) == super
True

To round out this answer, I will note something very, very obvious, but possibly worth mentioning here just in case. A variable might, and often does, differ from how its value is displayed. When you say

x = 3
print(x)

you don't expect the answer to be x, but 3, because that is the way the value inside x displays itself (via int.__str__ method). int is just another variable, one that happens to contain the integer type object. This type object displays itself as <class 'int'>, not int. int is just a variable name.

>>> my_shiny_number = int
>>> my_shiny_number()
0
>>> type(my_shiny_number())
<class 'int'>

And conversely (and please never ever do this in real code, this is for illustration purposes only):

>>> int = str
>>> int()
''
>>> type(int())
<class 'str'>

Upvotes: 1

Related Questions