Дизайн наследования классов Python: притворяться похожим на утку, но не крякать - PullRequest
0 голосов
/ 27 мая 2018

Я искал это сегодня несколько часов, но не получил недавнего и удовлетворительного окончательного ответа.

Предположим, у нас есть два конкретных класса, которые имеют как перекрывающиеся имена методов, так и конкретные отдельные методы.Избавляясь от лишних частей, давайте поработаем со следующими классами.

class A():
    def __init__(self, a_arg1, a_arg2):
        self.a_arg1 = a_arg1
        self.a_arg2 = a_arg2

    @property
    def gimme_1(self):
        return self.a_arg1

    @property
    def gimme_2(self):
        return self.a_arg2

    @property
    def prop(self):
        return 'A'

, а также

class B():
    def __init__(self, b_arg1, b_arg2, b_arg3):
        self.b_arg1 = b_arg1
        self.b_arg2 = b_arg2
        self.b_arg3 = b_arg3

    @property
    def give_1(self):
        return self.b_arg1

    @property
    def give_2(self):
        return self.b_arg2

    @property
    def give_3(self):
        return self.b_arg3

    @property
    def prop(self):
        return 'B'

Моя цель - создать третий класс, который может превратиться в один из них, а именно, он будет иметь все методы, которые эти два имеют, и действоватькак будто это один из них, в зависимости от того, что требуется.Это мотивация для названия вопроса.

class C(A, B):
    def __init__(self, some_list):
        self.some_list = some_list

    @property
    def gimme_1(self):
        return self.some_list[0]

    @property
    def gimme_2(self):
        return self.some_list[1]

    @property
    def give_1(self):
        return self.some_list[0] ** 2

    @property
    def give_2(self):
        return self.some_list[1] ** 2

    @property
    def give_3(self):
        return self.some_list[2]

    @property
    def prop(self):
        return 'C'

Конкретные вопросы:

  1. Нужно ли инициализировать родителей для этого конкретного случая?Если да, как следует использовать super().
  2. Это действительно помогло бы мне избавиться от запросов типа isinstance(x, A) или isinstance(x, B).Есть ли лучшие практики , которые препятствуют такому использованию?Обратите внимание, что печатание утки Pythonic на самом деле не так важно для меня в моем случае.Для разных вычислительных алгоритмов обязательно должно быть много ветвлений.Поэтому я действительно использую классы в качестве контейнеров для объединения данных, но не использую их в качестве регистраторов состояний.Другими словами, данные их экземпляров почти никогда не меняются.Но их данные используются в разных ветках в зависимости от того, к какому классу они относятся.Поэтому для меня важно получить правильный вид объекта.

1 Ответ

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

Вместо того, чтобы переписывать методы, почему бы не воспользоваться преимуществами наследования?Позвольте родителям __init__ позаботиться о настройке значений экземпляров и предоставьте им реализации методов.

class C(A, B):
    def __init__(self, arg1, arg2, arg3):
        A.__init__(self, arg1, arg2)
        B.__init__(self, arg1**2, arg2**2, arg3)

    @property
    def prop(self):
        return 'C'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...