我有以下简单的代码,
class A:
def __init__(self):
self.value = "789"
def method1(self):
return "valueA"
class B(A):
def __init__(self):
super(B, self).__init__()
def call_parent_method(self):
return super().method1()
def call_parent_value(self):
return super().value
b = B()
print(b.call_parent_method())
print(b.call_parent_value())
b.call_parent_method()
运行良好,而 b.call_parent_value()
抛出以下异常:
AttributeError: 'super' object has no attribute 'value'
我知道 self.value
有效,但我只想知道为什么 super().value
无效。
答案 0 :(得分:4)
因为你继承了类属性但没有继承实例属性。它们属于类的特定实例。
当您在类 B
中时,value
是 B
的实例属性,而不是 A
。如果 value
是一个类属性,您可以使用 super().value
访问它,例如:
class A:
value = 5
class B(A):
def get_value(self):
return super().value
b = B()
print(b.get_value())
答案 1 :(得分:0)
Guido van Rossum 提供了 super()
的 a pure Python version ,这可能会清楚地了解 super()
是如何工作的(C 实现细节在 {{3} 中的 super_getattro()
}).
看看__getattr__
的最后一部分,我们就会知道Objects/typeobject.c。上面的 super().value
等价于 super(B, self).__getattr__("value")
。
class Super(object):
def __init__(self, type_, obj=None):
self.__type__ = type_
self.__obj__ = obj
def __get__(self, obj, cls=None):
if self.__obj__ is None and obj is not None:
return Super(self.__type__, obj)
else:
return self
def __getattr__(self, attr):
if isinstance(self.__obj__, self.__type__):
start_type = self.__obj__.__class__
else:
start_type = self.__obj__
mro = iter(start_type.__mro__)
for cls in mro:
if cls is self.__type__:
break
# Note: mro is an iterator, so the second loop
# picks up where the first one left off!
for cls in mro:
if attr in cls.__dict__:
x = cls.__dict__[attr]
if hasattr(x, "__get__"):
x = x.__get__(self.__obj__)
return x
raise AttributeError(attr)