Дочерний класс наследует родительский класс self.variable

#python #python-3.x #class #inheritance

#python #python-3.x #класс #наследование

Вопрос:

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

Ниже приведены мои проблемы:

 class Parent(object):
    def __init__(self,**kwargs):
        self.name = kwargs.get('name',None)
        self.age = kwargs.get('age',None)
        self.year = '1995'
        print(self.name,self.age,self.year)

class Child(Parent):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.parent_name = self.name
        self.parent_age = self.age
        self.parent_year = self.year
        print("Parent Details: ",self.parent_name,self.parent_age,self.parent_year)

>>> res = Parent(name='Derek',age=22)
Derek 22 1994
>>> res2 = Child()
None None 1994
  

Мой вопрос в том, почему дочерний класс возвращает None? Я уже использовал super() для наследования родительского класса init. Ниже приведены мои ожидания и как я могу этого достичь?

 >>> res = Parent(name='Derek',age=22)
Derek 22 1994
>>> res2 = Child()
Parent Details: Derek 22 1994
  

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

1. Ваши ожидания странные / плохие. Child() был создан без какого-либо имени и возраста, почему он должен повторно использовать данные из какого-либо другого не связанного экземпляра?

2. Вы не передали имя или возраст при создании экземпляра Child , поэтому, естественно, у этого экземпляра нет имени или возраста.

3. Предположим, у вас есть два объекта p1 = Parent(name="Derek", age=22) и p2 = Parent(name="Donna", age=21) . Какие значения вы ожидаете Child() унаследовать? Наследование применяется к поиску имен в иерархии классов , а не к отношениям между отдельными экземплярами этих классов.

4. Вам следует пока избегать использования **kwargs . Кажется, это затрудняет ваше понимание того, что происходит.

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

Ответ №1:

Наследование, грубо говоря, имеет дело с концепциями уровня класса. Рассмотрим этот родительский класс:

 class Parent(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.year = '1995'

    def eat(self, food):
        print("I ate {}".format(food))
  

Теперь рассмотрим этот дочерний класс:

 class Child(Parent):
    def __init__(self, name, age, p):
        super().__init__(name, age)
        self.parent_name = p.name
        self.parent_age = p.age
        self.parent_year = p.year
        # Or, since you can already access the name, age, and year of
        # an instance of Parent, just save the instance directly:
        self.parent = p
  

Тогда вы могли бы написать

 p = Parent("Derek", 22)
c = Child("Didi", 9, p)
  

Теперь c.parent_name == "Derek" и c.parent_age == 22 , но c.name == "Didi" и c.age == 9 . Вы явно указали Child , кто был родителем Didi; наследование не задействовано. (Наследование участвует в настройке атрибутов name и age , поскольку вы вызываете super().__init__ , но это своего рода странная иерархия классов. Child является дочерним классом Parent , но на самом деле это не очень хорошо моделирует реальный мир: не все дочерние элементы являются родителями.)

Наследование происходит с помощью eat метода. Child.eat Метода не существует, поэтому при вызове c.eat("apple") происходит то, что Parent.eat вызывается с Child экземпляром в качестве первого аргумента.

 >>> p.eat("apple")
"I ate apple"
>>> c.eat("apple")
"I ate apple"
  

Наследование следует использовать для моделирования отношений «is-a»; если B наследуется от A , то по сути экземпляр B должен использоваться везде, где можно использовать экземпляр A . Ваше использование здесь нарушает это; a Child имеет родителя, но не обязательно сам является родителем, и поэтому Child не должен наследовать от Parent . Более разумное моделирование включало бы только один класс:

 class Person:
    def __init__(self, name, age, parents=None):
        self.name = name
        self.age = age
        self.parents = parents

# We've lost the genealogical records, and don't know who
# Bob and Alice's parents were.
first_man = Person("Alice", 25)
first_woman = Person("Bob", 25)
children = [
    Person("Charlie", 15, [first_man, first_woman]),
    Person("Derek", 13, [first_man, first_woman])
]
  

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

1. Спасибо за ваш ответ, я думаю, что основной смысл вашего ответа здесь — передать родительский класс дочернему классу. c = Дочерний класс(«Didi», 9, p)

2. Я все еще должен придерживаться ** kwargs, поскольку моя организация использует его. Однако я делаю следующее: c = Child(parent_class = p) а затем обрабатываю это с помощью p = kwargs.get(parent_class,None) , а затем продолжаю с self.parent_name = p.name

3. parent , не parent_class . p является экземпляром Parent , а не самим классом. Серьезно, убедитесь, что кто-то в вашей организации проводит проверку кода того, что вы пишете, потому что вы, похоже, недостаточно хорошо понимаете основы, чтобы писать что-либо самостоятельно.

4. opps .. понял. Да, есть старший … но он сейчас в отъезде. Итак, ищу помощь здесь