Правильный способ переопределения методов с незначительными изменениями в Python
Скажем, у меня есть класс
class Base(object):
def my_method(self, input):
print input #suppose this is many lines
print "mymethod" #so is this
И подкласс, имеющий метод, который делает почти то же самое, за исключением дополнительной операции в середине метода, например
class Sub(Base):
def mymethod(self, input): #how do I properly define this?
print input
print "some other stuff" #additional operation in the middle
print "mymethod"
Каков правильный способ переопределения mymethod
?
- я копирую и вставляю большинство
Base.mymethod()
? (Вероятно, нет - это определенно нарушает сухой). - должен ли я определить
Base.mymethod()
, чтобы иметь условный оператор для дополнительной операции, которая возвращает true только в случае подкласса? (Вероятно, нет - это не имеет смысла, так как базовый класс должен быть автономным, и это похоже на рецепт катастрофы) - могу ли я как-то использовать
super()
? (Кажется, что нет -Sub
дополнительная операция находится в середине метода, а не в начале или конце)
2 ответа:
Для такого простого примера я, скорее всего, скопирую эти три маленькие строки, даже если создам повторы. Старайтесь избегатьчрезмерной инженерии .
В случае, когда
my_method()
на самом деле сложнее, вы можете разделить свою функцию на три шага и позволить дочерним классам перегружать нужную им часть.class Base(object): def my_method(self, input): self._preprocess(input) self._process() self._postprocess() def _preprocess(self, input): print(input) def _process(self): pass def _postprocess(self): print("mymethod") class Sub(Base): def _process(self): print("some other stuff")
Конечно, вы должны использовать более осмысленные имена методов.
Это зависит от того, где вещи принадлежат. Обычно, если вы в конечном итоге хотите вставить материал между операциями метода базы, это означает, что метод на самом деле должен быть разделен на несколько методов.
Например:
class Base(object): def my_method(self, input): print input #suppose this is many lines print "mymethod" #so is this
Может стать:
Это позволяет подклассам переопределять весь процесс без необходимости повторной реализации каждого шага. Эта концепция сродни шаблонному методу , но наоборот.class Base(object): def my_method(self, input): self.do_first_thing(input) self.do_second_thing("mymethod") def do_first_thing(self, input): print(input) def do_second_thing(self, data): print(data)
(обычно точкой шаблона метода pattern является чтобы позволить подклассам переопределить шаги, здесь мы используем ту же структуру, чтобы позволить подклассам переопределить сам шаблон).