请解释为什么我不能使用super(class, self)
访问类继承层次结构中更高级别的类中定义的属性,以及如何访问它们。
根据文档,super(class, self
应该返回一个代理对象,我可以通过它访问父类实例中的def name()
。
- super([type[,object or type]])
返回一个代理对象,该对象将方法调用委托给父对象或类型的同级类。这对于访问继承的方法很有用已在类中重写的。
对象或类型确定要执行的方法解析顺序已搜索。搜索从类型后面的类开始。
例如,如果对象或类型的mro是D->B->C->A->对象,并且类型的值为B,则super()搜索C->A->对象
我认为super(Parent)
将为具有def name()
的GrandParent对象提供一个代理。
class GrandParent:
def __init__(self):
self._name = "grand parent"
@property
def name(self):
return self._name
class Parent(GrandParent):
def __init__(self):
super().__init__()
self._name = "parent"
@property
def name(self):
return super().name
class Child(Parent):
def __init__(self):
super().__init__()
self._name = "child"
@property
def name(self):
return super(Parent).name
print(Child().name)
---
AttributeError: 'super' object has no attribute 'name'
如果没有(class, self)
,它将返回。。。子财产。显然,我还不了解self
和super
在Python中是如何工作的。请建议要查看哪些资源以充分了解行为和设计。
class GrandParent:
def __init__(self):
self._name = "grand parent"
@property
def name(self):
return self._name
class Parent(GrandParent):
def __init__(self):
super().__init__()
self._name = "parent"
@property
def name(self):
return super().name
class Child(Parent):
def __init__(self):
super().__init__()
self._name = "child"
@property
def name(self):
return super().name
print(Child().name)
---
child
self
总是指同一个对象。执行super().__init__()
时,父对象的__init__
中的self
是Child
的实例。GrandParent.__init__
只是在该对象上设置一个属性。通过链接所有这些__init__
,你实际上只是在做这个:
o = object()
o._name = 'grand parent'
o._name = 'parent'
o._name = 'child'
您只是覆盖_name
属性,其中只有一个属性。所有不同的@property
只返回这一个_name
属性的值,您的对象只有一个属性,其值为'child'
。
如果希望对象每个父对象都有一个单独的_name
属性,那么实际上必须创建单独的属性。最简单的方法可能是使用Python的双下划线名称mangling;私有属性":
>>> class A:
... def __init__(self):
... self.__foo = 'bar'
... @property
... def foo(self):
... return self.__foo
...
>>> class B(A):
... def __init__(self):
... super().__init__()
... self.__foo = 'baz'
... @property
... def foo(self):
... return super().foo
...
>>> B().foo
'bar'
>>> vars(B())
{'_A__foo': 'bar', '_B__foo': 'baz'}
实际属性被命名为_A__foo
和_B__foo
,因此彼此不冲突。