【问题标题】:Child class inherit Parent class self.variable子类继承父类self.variable
【发布时间】:2019-03-06 21:46:59
【问题描述】:

我不确定是否有人问过这个问题,因为我看不到任何类似的问题。

以下是我的问题:

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

【问题讨论】:

  • 您的期望很奇怪/很糟糕。 Child() 是在没有任何名称和年龄的情况下创建的,它为什么要重复使用来自其他不相关实例的数据?
  • 您在创建Child 的实例时没有传递姓名或年龄,因此该实例自然没有姓名或年龄。
  • 假设您有两个对象p1 = Parent(name="Derek", age=22)p2 = Parent(name="Donna", age=21)。您希望Child() 继承哪些值?继承适用于 class 层次结构中的名称查找,而不适用于这些类的各个 instances 之间的关系。
  • 你现在应该避免使用**kwargs。它似乎使您无法理解正在发生的事情。
  • 我无法确定,但在我看来,您似乎在混淆类和类的实例。这是非常不同的事情。

标签: python python-3.x class inheritance


【解决方案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滴滴的父母是谁;不涉及继承。 (继承涉及设置nameage 属性,因为您调用super().__init__,但这是一种奇怪的类层次结构。Child 是@987654333 的子类@,但这并不能很好地模拟现实世界:并非所有孩子都是父母。)

继承来自eat 方法。没有Child.eat 方法,所以当您调用c.eat("apple") 时,会发生Parent.eatChild 实例作为其第一个参数来调用。

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

应该使用继承来模拟“is-a”关系;如果B 继承自A,那么出于所有意图和目的,B 的实例应该可以在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])
]

【讨论】:

  • 感谢您的回答,我认为您在这里回答的重点是将父类传递给子类。 c = Child("滴滴", 9, p)
  • 我仍然坚持使用 **kwargs,因为我的组织正在使用它。但是,我所做的如下:c = Child(parent_class = p) 然后使用p = kwargs.get(parent_class,None) 处理它,然后使用self.parent_name = p.name
  • parent,而不是parent_classpParent实例,而不是类本身。说真的,请确保您组织中的某个人对您正在编写的任何内容进行代码审查,因为您似乎对基础知识的掌握不够牢固,无法自己编写任何内容。
  • opps..明白了。是的,有一个前辈..但他现在不在。所以在这里寻求帮助
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 2012-04-11
  • 1970-01-01
  • 1970-01-01
  • 2015-03-14
  • 2019-03-16
  • 2013-02-16
  • 2019-12-28
相关资源
最近更新 更多