как можно объявить объект подкласса внутри базового класса, не приводя к ошибкам рекурсии? - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь структурировать программу на Python 3 следующим образом:

Базовый класс : тело

подкласс : голова

Супер-простое представление кода выглядит следующим образом:

class Body:
    def __init__(self):
        self.head_obj = Head()
        # ...Set-up body...

    def body_actions:
        print('Body does something')


class Head(Body):
    def __init__(self):
        super().__init__()
        # ...Set-up head...

    def head_actions:
        print('Head does something')

Я хочу иметь возможность создать экземпляр Body с именем body_obj и затем получить доступ к подклассу Head (и его свойствам)./ method) следующим образом:

body_obj = Body()
body_obj.body_actions()
body_obj.head_obj.head_actions()

Однако, когда я запускаю код, Python возвращает максимальную глубину рекурсии RuntimeError.

Мне нужно выполнить некоторые настройки с __ init __ в обоихКлассы Body и Head, а Pycharm жалуется, когда я не вызываю функцию super () в классе __ init ___ класса Head, поскольку это кажется плохой практикой.

Как правильно настроить этот типструктуры, где все дочерние объекты Класса должны быть инициализированы при создании экземпляра базового класса?

Я изучил вложение классов, но это также кажется плохой практикой.

1 Ответ

0 голосов
/ 27 сентября 2018

Голова - это не вид тела, это часть тела AFAIK.

Так что вы должны использовать состав вместо наследование :

class Head:
    def __init__(self):
        # ...Set-up head...

    def head_actions():
        print('Head does something')

class Body:
    def __init__(self):
        self.head = Head()
        # ...Set-up body...

    def body_actions:
        print('Body does something')

Теперь вы можете сделать:

body = Body()
body.body_actions()
body.head.head_actions()

Причина, по которой вы получаете бесконечную рекурсию, заключается в том, что ваш Body является суперклассом Head, поэтому, когда вы вызываете super().__init__(), вы создаете экземпляр Body, который в вашей реализации создает Head, который вызывает super().__init__() и так далее.

Композиция (если это то, что вы подразумеваете под «вложением») - это не плохая практика, это стандартная практика и часто имеет больше смысла, чем наследование.


Редактировать в ответ накомментарий

Для доступа к методам Body из Head вы можете передать ссылку на Body при создании.Поэтому переопределите классы следующим образом:

class Head:
    def __init__(self, body):
        self.body = body

    def head_actions():
        print('Head does something')

class Body:
    def __init__(self):
        self.head = Head(self)

    def body_actions:
        print('Body does something')

Теперь вы можете получить доступ к голове из тела, а тело из головы:

body = Body()
head = body.head
head.body.body_actions()

Или даже

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