#python #python-3.x #class
Вопрос:
Я хотел бы сделать 2 вещи:
-
- Создайте столько раз дочерний класс из экземпляра родительского класса (что я могу сделать)
-
- Вызов метода родительского класса из экземпляра дочернего класса (что я не могу сделать)
Чтобы проиллюстрировать свою проблему, я создал 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
объект. Это определяет, у какого родителя спросить время. Это неэффективно .