超级能够访问父类的属性

2024-04-25 15:21:01 发布

您现在位置: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无效


Tags: 代码selfreturninitvaluedefcallmethod
2条回答

因为您继承类属性,但不继承实例属性。它们属于类的特定实例

当您在类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())

Guido van Rossum提供了super()中的a pure Python version,这可以清楚地看到super()是如何工作的(C实现的详细信息在super_getattro()中的Objects/typeobject.c

看看__getattr__的最后一部分,我们会知道super() works for class attribute lookup。上述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)

相关问题 更多 >