В заметке расскажу, как переопределить свойства (@property
) в классе-наследнике. Как оказалось, это не тривиально и существуют несколько вариантов, различных между собой.

Допустим есть базовый класс со свойством:
class Base: def __init__(self): self._x = 100 @property def x(self): print('Base get x') return self._x @x.setter def x(self, value): print('Base set x') self._x = value
Ситуация А. В классе-наследнике мы хотим переопределить ТОЛЬКО сеттер, чтобы он делал что-то еще помимо того, что умеет в базовом классе. Это не так и тривиально:
class Derived1(Base): @Base.x.setter def x(self, value): print('Derived1 set x') Base.x.fset(self, value)
Ситуация B. Хотим переопределить ТОЛЬКО геттер:
class Derived3(Base): @Base.x.getter def x(self): print('Derived3 get x') return super().x
Ситуация C. Хотим переопределить и геттер, и сеттер.
class Derived2(Base): @property def x(self): print('Derived2 get x') return super().x @x.setter def x(self, value): print('Derived2 set x') Base.x.fset(self, value)
В этом случае мы определяем свойство как бы с нуля. Старый геттер вызывается при доступе к super().x
, а старый сеттер вызываем аналогично с ситуацией A. Разница только в @x.setter
вместо @Base.x.setter
(по-старому не работает, проверял).
Я специально разделил пост на три ситуации, потому в каждой из них работает свой подход, а другие комбинации, которые я пробовал, не работают.
Как сделать проще? Писать все геттеры и сеттеры явно, а потом делать из них property
; или вообще отказаться от property
.
class Base: def __init__(self): self._x = 0 def set_x(self, v): print('Base set x') self._x = v def get_x(self): print('Base get x') return self._x x = property(get_x, set_x) class Derived(Base): def set_x(self, v): print('Derived set x') super().set_x(v) def get_x(self): print('Derived get x') return super().get_x() x = property(get_x, set_x)
Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway 👈