Правильный способ переопределения методов с незначительными изменениями в Python - PullRequest
0 голосов
/ 09 мая 2018

Скажите, у меня есть класс

class Base(object):
    def my_method(self, input):
        print input #suppose this is many lines
        print "mymethod" #so is this

и подкласс, который имеет метод, который делает почти то же самое, за исключением дополнительной операции в middle метода, например

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 ]

0 голосов
/ 09 мая 2018

Для такого простого примера я, скорее всего, скопирую эти три маленькие строки, даже если создаст повторения.Старайтесь избегать чрезмерного проектирования .

В случае, если 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")

Конечно, вы должны использовать более значимые имена методов.

0 голосов
/ 09 мая 2018

Это зависит от того, где вещи принадлежат.Обычно, если вы захотите вставить материал между операциями метода base, это означает, что метод должен быть фактически разбит на несколько методов.

Например:

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)

Это позволяет подклассам переопределять весь процесс без необходимости повторной реализации каждого шага.Концепция похожа на шаблонный метод , но в обратном направлении.

(Обычно смысл шаблона шаблонного метода состоит в том, чтобы позволить подклассам переопределять шаги, здесь мы используем ту же структуру, чтобы позволить подклассам переопределятьсам шаблон).

...