超级能够访问父类的属性

时间:2021-01-19 07:03:16

标签: python

我有以下简单的代码,

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 无效。

2 个答案:

答案 0 :(得分:4)

因为你继承了类属性但没有继承实例属性。它们属于类的特定实例。

当您在类 B 中时,valueB 的实例属性,而不是 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)