super(Foo,self)和super(Foo,self .__ class__)之间的区别?

时间:2015-09-18 02:33:28

标签: python python-3.x

我对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)

任何指导都将不胜感激。

1 个答案:

答案 0 :(得分:2)

为简化起见,我们假设(如您的示例中)super始终返回Foo中定义的内容的代理,也就是说,不涉及其他类。< / p>

  1. 暂时忽略对super的来电,考虑bar.xBar.x之间的区别。第一个会调用命名属性的getter;后者只是对房产本身的参考。

  2. 现在考虑一个非属性属性。 super(Bar, self).method将是绑定方法的一个实例,因此super(Bar, self).method(x)将等同于Foo.method(self, x)。但是,super(Bar, self.__class__).method将是未绑定的方法,即只是Foo.method

  3. 现在结合步骤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的实例selfBar是对property中定义的Foo对象的引用。