python:为什么 `type(super())` return <class 'super'>?

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

一个简短的继承示例:

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()))

现在输入 Student("test", "name") 将导致 <class 'super'> 被打印到控制台。我不熟悉这种格式。当我执行 type(int) 时,我看到的类型是 type,而不是 <class 'int'>。有人可以解释这里发生了什么吗?

如果你看一下 docs,

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

这个代理对象的类型是super;假设 super_object = super(),那么 type(super_object) returns 一个描述所有超级对象所属的 class 的类型对象。就像 type(0) returns 一个描述整数的类型对象。 <class 'int'> 是此类型对象打印自身的方式。有趣的事实:你已经知道这个对象了。

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

请注意,在 Python 中,class 的构造函数是类型对象本身。所以当你写int()时,你是在构造一个新的int类型的对象,就像你写Student("test", "name")时,你是在构造一个Student类型的新对象。 super 也是如此:

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

为了完善这个答案,我会注意到一些非常非常明显但可能值得一提的事情,以防万一。变量可能而且经常会与其值的显示方式不同。当你说

x = 3
print(x)

您不希望答案是 x,而是 3,因为这是 x 中的值显示自身的方式(通过 int.__str__ 方法). int 只是另一个变量,恰好包含整数类型对象。此类型对象将自身显示为 <class 'int'>,而不是 intint只是一个变量名。

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

反过来(请永远不要在实际代码中这样做,这仅用于说明目的):

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