2015-09-18 2 views
2

Я очень новичок в python, поэтому надеюсь, что я не пропущу слишком много необходимых знаний, чтобы понять это, но ...Разница между супер (Foo, self) и супер (Foo, self .__ class__)?

У меня есть класс с некоторыми свойствами, и я пытаюсь переопределить сеттер на один из них похож на этот пример:

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) 

... и как это ди ffers из этой линии, которая не работает:

super(Bar, self).x.fset(self, value) 

Любые указания будут оценены.

ответ

1

Для упрощения мы предположим (как в вашем примере), что super всегда возвращает прокси-сервер для чего-то определенного в Foo, то есть других классов не участвует.

  1. Игнорировать вызов super на данный момент, рассмотрим разницу между bar.x и Bar.x. Первый будет ссылаться на getter для именованного свойства; последнее - это просто ссылка на само свойство.

  2. Теперь рассмотрим атрибут non-property. 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 называться, и мы знаем, что super(Bar, self) является прокси для Foo через self. Следовательно, super(Bar, self).x должен вызывать геттер, определенный не в Bar, а в Foo.

    Мы также знаем, что Bar.x - это просто ссылка на объект property, который не вызывает его получение; и мы знаем, что super(Bar, self.__class__) действует как прокси-сервер для Foo независимо от любого конкретного объекта. Поэтому мы можем заключить, что super(Bar, self.__class__).x, для примера self от Bar, является ссылкой на объект property, определенный в Foo.

+0

Это имеет большой смысл. Спасибо за очень четкий ответ! – Ocelot20

Смежные вопросы