Python在父级init中创建子级对象,并可以访问父级属性

时间:2019-06-12 20:28:29

标签: python python-3.x class oop

我想创建一个父对象,该对象创建其子对象,并且其子对象需要访问其中一个父属性。

我已经找到了在父级内部创建子级的方法以及访问父级属性之一的方法,但是没有办法同时做这两项。

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 :(得分:0)

好的,我不得不说这似乎不是对继承的适当使用。继承应用于为具有共同点的不同类提供多个属性和方法集。在初始化时从父母那里给孩子打电话似乎有点可疑。

不过,我想比这个例子有更广泛的原因。因此,我可以提供一种不需要Child使用super()(如注释中所指定)的解决方案。

但是,此解决方案有一个警告,也是一个很大的警告。 self.number成为类方法,因此,如果使用不同的Parent实例化新的number,它将更改先前实例化的Parent

就这样:

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