为什么super().__ class __.__ name__不返回我的基类的名称?

时间:2019-05-05 17:42:13

标签: python-3.x super superclass introspection

我有一个继承自基类A的类,以创建类B。如果在类实例上调用名称dunder,则会得到该类的名称。如果在实例的基类上调用名称dunder,则将获得基类的名称。到目前为止,这是有道理的。但是,如果在实例的super()上调用名称dunder,则无法获取基类的名称,并且不确定为什么。为了使事情更加混乱,如果我在supers()的基类上调用名称dunder,则会得到基类的基类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...

打印出

B
A
super 
object

我不明白为什么我的should_return_base_class_name通话会返回“ super”。

2 个答案:

答案 0 :(得分:2)

这是因为super实际上是一个抽象类,可以抽象出您的基类。超级实际上不是基类。当您执行super()时,您将获得超类的实例,而不是基类的实例。
如果您在示例中尝试使用print(super()),则会得到<super: <class 'B'>, <B object>>

答案 1 :(得分:2)

super()返回一个super对象。如果您向Python请求__name__对象的__class__中的super,它将告诉您该名称为super

请参见official documentationsuper()返回一个代理对象,而不是您(我想)期望的基类对象。

您需要访问super的__class__的事实应该暗示这一点,因为如果super()返回了基类本身,则它已经是一个类,并且无法返回实例之所以这样,是因为没有迹象表明会是哪个实例。