Наследование с использованием функции в качестве конструктора базового объекта - PullRequest
2 голосов
/ 30 сентября 2019

Я импортировал пакет, который предоставляет мне класс и функцию-обертку, которая создает экземпляр этого класса. Например:

class Foo:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def print_a(self):
        print(self.a)

    def print_b(self):
        print(self.b)


def makeFoo(x, y):
    a = x + y
    b = x - y
    return Foo(a, b)

Я хочу иметь подобный класс NamedFoo, который имеет те же свойства / методы, также имеет свойство name и имеет конструктор, который вызывает makeFoo. Я полагаю, что это должно быть решено с использованием наследования, при этом NamedFoo является подклассом Foo. Однако я не знаю, как заставить конструктор NamedFoo правильно использовать makeFoo:

class NamedFoo(Foo):
    def __init__(self, x, y, name):
        # ???
        # Foo = makeFoo(x, y)   ??
        # self.Foo = makeFoo(x, y)  ??
        self.name = name

    def printName(self):
        print(self.name)

Пример данных:

myNamedFoo = NamedFoo(2,5,"first")
myNamedFoo.print_a()  # (From makeFoo: a = x + y) ==> 2 + 5 = 7
myNamedFoo.print_b()  # (From makeFoo: a = x - y) ==> 2 - 5 = -3

Я не слишком знаком с объектомориентированное на программирование, так что я могу просто использовать неправильные условия поиска, но я не нашел ничего похожего на то, что мне нужно. Возможно ли это, и если да, то как я могу это сделать?

Я также не уверен, является ли это проблемой X / Y, но вот альтернативы, которые я рассмотрел, и почему я не думаю,они идеальны:

  • Состав Foo и свойство name: Это уродливо и не кажется правильным.
  • Вручную добавить свойство name к каждому Foo объекту и, возможно, обернуть его в функцию: не совсем элегантно, как конструктор с одним вкладышем.
  • Переписать конструктор для класса Foo, чтобы тот же код, что и в makeFoo: makeFoo, довольно сложный и требует большой настройки, и это в любом случае привело бы кдля дублирования кода

Ответы [ 2 ]

2 голосов
/ 30 сентября 2019

В конструкторе NamedFoo создайте экземпляр класса Foo из функции-оболочки makeFoo. Передайте атрибуты этого экземпляра в super().__init__.

class NamedFoo(Foo):
    def __init__(self, x, y, name):
        _foo = makeFoo(x,y) # use the wrapper to handle complex logic from input params
        super().__init__(_foo.a,_foo.b) # pass the properly derived Foo attributes to the superclass constructor
        self.name = name

Таким образом, мы создаем экземпляр NamedFoo из любой магии, происходящей в функции makeFoo. Передайте ваши x и y тому, что создаст одноразовый экземпляр Foo (чтобы мы могли правильно построить его с любой сложной логикой, находящейся в вспомогательной функции). Окончательный класс NamedFoo затем создается из конструктора Foo.

enter image description here

0 голосов
/ 30 сентября 2019

я думаю, что это должно работать ..

class Foo:
    def __init__(self,a,b):
        self.a = a + b
        self.b = a - b

    def print_a(self):
        print(self.a)

    def print_b(self):
        print(self.b)


class NamedFoo(Foo):
    def __init__(self,a,b,name):
        super().__init__(a,b)
        self.name = name


def main():
    example = NamedFoo(2,5,"first")
    example.print_a()
    example.print_b()

main()

это распечатывает

7
-3

или если вы действительно хотите использовать функцию для создания self.a и self.b useэто:

class Foo:
    def __init__(self, a, b):
        self.a, self.b = make_foo(a,b)

    def print_a(self):
        print(self.a)

    def print_b(self):
        print(self.b)


class NamedFoo(Foo):
    def __init__(self, a,b,name):
        super().__init__(a,b)
        self.name = name


def make_foo(x,y):
    return x+y, x-y

def main():
    example = NamedFoo(2,5,"first")
    example.print_a()
    example.print_b()

main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...