Создайте экземпляры дочернего класса из экземпляра родительского класса и вызовите родительские методы из экземпляра дочернего класса

#python #python-3.x #class

Вопрос:

Я хотел бы сделать 2 вещи:

    1. Создайте столько раз дочерний класс из экземпляра родительского класса (что я могу сделать)
    1. Вызов метода родительского класса из экземпляра дочернего класса (что я не могу сделать)

Чтобы проиллюстрировать свою проблему, я создал 2 экземпляра class Parent , к которым я добавляю экземпляр class Child в каждый.

 from datetime import datetime, timedelta


class Child:

    def __init__(self):
        pass

    def ask_time(self):                     # This function doesn't work,
        return self.read_time()             # But I would like to be able to call here the "read_time()" method of the class "Parent"


class Parent:

    def __init__(self, name, minutes_fast):
        self.name = name
        self.minutes_fast = minutes_fast
        self.children = {}

    def add_child(self, name):              # Construct "Child" class instance from class "Parent" class instance
        self.children[name] = Child()       # Because of this line, I cannot inherit "class Child (Parent):"

    def get_child(self, name):
        if name not in self.children:
            self.add_child(name)
            return self.children[name]

    def read_time(self):
        current_time = datetime.now()
        delta = timedelta(minutes=self.minutes_fast)
        return (current_time   delta).strftime("%H:%M:%S")


# Add the Parent "James" who is 3 minutes early to his watch, and add him the child "John"
parent1 = Parent("James", 3)
child1 = parent1.get_child("John")

# Add the Parent "Michael" who is 1 minutes early to his watch, and add him the child "Matthew"
parent2 = Parent("Michael", 1)
child2 = parent2.get_child("Matthew")


print(parent1.read_time())
print(parent2.read_time())
 

В моем случае использования ответственность за чтение времени лежит class Parent на . Поэтому я добавил этот read_time() метод к этому.
Но экземпляр class Child должен иметь возможность запрашивать время у экземпляра class Parent , который его создал. Поэтому я добавляю ask_time() метод к class Child тому, который вызывает read_time() метод class Parent … Что не работает без наследования между моими классами (следующим образом class Child(Parent): ).

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

 print(child1.ask_time())
print(child2.ask_time())
 

Но я не вижу, как наследовать, когда class Parent сам зависит от class Child ?
Спасибо за вашу помощь !

Комментарии:

1. Вам нужно было бы явно передать Parent экземпляр при создании Child ; Child.__init__() возможно, вы сохранили бы его self.parent , тогда вы могли бы это сделать self.parent.read_time() .

2. @jasonharper Спасибо. Это та же идея, что и ответ, сделанный Черносливом

Ответ №1:

Вы перепутали функциональную зависимость с наследованием классов. Вам не нужно наследовать read_time от Parent . На самом деле, ваша реализация показывает, что этого недостаточно. Как вы правильно спроектировали, read_time это атрибут экземпляра: нет смысла вызывать read_time , не указав, какой Parent экземпляр должен отвечать.

Вам нужно дать каждому ребенку ссылку на его родителя. Включите это в add_child :

 def add_child(self, name):
    baby = Child(self, name)
    self.children[name] = baby
 

Измените Child инициализацию, чтобы использовать соответствующую информацию:

 def __init__(self, parent, name):
    self.parent = parent
    self.name = name
 

Кажется глупым, чтобы имя ребенка было свойством только родительского списка.

Теперь, когда ребенку нужно спросить время, у нас есть:

 def ask_time(self):
    return self.parent.read_time()
 

Комментарии:

1. Спасибо @Prune, я понимаю вашу идею и очень четкие объяснения. Является ли это лучшей практикой для этого? Потому что у меня сложилось впечатление , что, делая это, мы перегружаем экземпляры class Child , верно?

2. Что вы подразумеваете под «перегрузкой экземпляров»? Стандартная практика заключается в разработке отношений между классами до того, как вы начнете кодировать. Вы задумали отношения между родителями и детьми, но не учли необходимость ссылок во взаимодействии классов. Вы можете изучить методы UML (унифицированный язык моделирования), чтобы получить представление о том, как использовать этап проектирования.

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

4. Что вы подразумеваете под «но не следовали необходимости в ссылках при взаимодействии с классом»? Означает ли это, что я мог бы поступить иначе?

5. Определите «необходимо». Да, вы можете продолжать хранить всю информацию в родителях. Затем каждый раз , когда вы хотите позвонить ask_time , вы получаете глобальный доступ к Parent классу, просматриваете всех детей всех родителей, пока не найдете текущий Child объект. Это определяет, у какого родителя спросить время. Это неэффективно .