我有一个继承自基类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”。
答案 0 :(得分:2)
这是因为super实际上是一个抽象类,可以抽象出您的基类。超级实际上不是基类。当您执行super()
时,您将获得超类的实例,而不是基类的实例。
如果您在示例中尝试使用print(super())
,则会得到<super: <class 'B'>, <B object>>
答案 1 :(得分:2)
super()
返回一个super
对象。如果您向Python请求__name__
对象的__class__
中的super
,它将告诉您该名称为super
。
请参见official documentation:super()
返回一个代理对象,而不是您(我想)期望的基类对象。
您需要访问super的__class__
的事实应该暗示这一点,因为如果super()
返回了基类本身,则它已经是一个类,并且无法返回实例之所以这样,是因为没有迹象表明会是哪个实例。