我对python非常陌生,所以希望我不缺少太多必要的知识来理解这一点,但是...
我有一个包含一些属性的类,我试图在其中一个上覆盖setter,类似于这个例子:
class Foo(object):
def __init__(self):
self._x = True
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
class Bar(Foo):
@property
def x(self):
return super().x
@x.setter
def x(self, value):
print('x set')
super(Bar, self.__class__).x.fset(self, value)
bar = Bar()
# Prints 'x set' as expected:
bar.x = True
这很好用,但我真的不明白为什么这条线的运作方式......
super(Bar, self.__class__).x.fset(self, value)
......以及它与这一行的区别,它不起作用:
super(Bar, self).x.fset(self, value)
任何指导都将不胜感激。
答案 0 :(得分:2)
为简化起见,我们假设(如您的示例中)super
始终返回Foo
中定义的内容的代理,也就是说,不涉及其他类。< / p>
暂时忽略对super
的来电,考虑bar.x
和Bar.x
之间的区别。第一个会调用命名属性的getter;后者只是对房产本身的参考。
现在考虑一个非属性属性。 super(Bar, self).method
将是绑定方法的一个实例,因此super(Bar, self).method(x)
将等同于Foo.method(self, x)
。但是,super(Bar, self.__class__).method
将是未绑定的方法,即只是Foo.method
。
现在结合步骤1和2.我们知道bar.x
将导致调用Bar
中定义的getter,并且我们知道super(Bar, self)
是Foo
的代理{1}}通过self
。因此,super(Bar, self).x
必须调用Bar
中未定义但在Foo
中定义的getter。
我们也知道Bar.x
只是对property
对象的引用,它不会调用它的getter;我们知道super(Bar, self.__class__)
充当Foo
的代理,独立于任何特定对象。因此,我们可以得出结论:对于super(Bar, self.__class__).x
的实例self
,Bar
是对property
中定义的Foo
对象的引用。