Python Create дочерние объекты в родительском init с доступом к родительским атрибутам - PullRequest
0 голосов
/ 12 июня 2019

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

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

class Parent():
    def __init__(self,number):
        self.number = number
        self.children = [Child(0), Child(2)]
class Child(Parent):
    def __init__(self, number2):
        self.number2 = number2
    def printNumber(self):
        print(self.number+self.number2)

Я ожидаю:

par = Parent(3)
par.children[0].printNumber()
<3>
par.children[1].printNumber()
<5>

Но произойдет сбой, потому что par.children [0] .number не существует.

1 Ответ

0 голосов
/ 13 июня 2019

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

Тем не менее, я предполагаю, что для этого есть более широкая причина, чем в этом примере. Поэтому я могу предложить решение, которое не требует Child для использования super() (как указано в комментариях).

У этого решения есть предостережение и большое. self.number становится методом класса, и, таким образом, если создается новый Parent с другим значением number, он изменит ранее созданный экземпляр Parent s.

Так что вот так:

class Parent():
    number = 0
    def __init__(self, number):
        self._change_number(number)
        self.children = [Child(0), Child(2)]

    @classmethod
    def _change_number(cls, number):
        cls.number = number

class Child(Parent):
    def __init__(self, number2):
        self.number2 = number2
    def printNumber(self):
        print(self.number+self.number2)

par = Parent(3)
par.children[0].printNumber()
# 3
par.children[1].printNumber()
# 5

Снова помните, что число является переменной класса !! . Затем, продолжив скрипт с:

pir = Parent(5)  # Different instance
# changes the values in the previous instance par
par.children[0].printNumber()
# 5
par.children[1].printNumber()
# 7

Я не вижу другого решения для этой работы, так как без вызова super из Child нет другого способа инициализировать атрибут self.number, если он не является классовым.

Если вы не хотите, чтобы это происходило, одним из вариантов будет вычисление self.number2 в __init__ времени. Тогда значение будет безопасно храниться без проблем. В этом случае Child будет выглядеть так:

class Child(Parent):
    def __init__(self, number2):
        self.number2 = self.number+number2
    def printNumber(self):
        print(self.number2)

И новый экземпляр не повлияет на предыдущий:

par = Parent(3)
par.children[0].printNumber()
# 3
par.children[1].printNumber()
# 5
pir = Parent(5)  # Different instance
# DOES NOT change the values in the previous instance par
par.children[0].printNumber()
# 3
par.children[1].printNumber()
# 5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...