python类继承:派生类问题的构造函数

时间:2012-11-21 21:53:17

标签: python class inheritance constructor derived

我有两个类:基类A和派生类B.在B的构造函数中,我尝试使用A的构造函数初始化实例。为什么分配" self = A(x)"在派生类的构造函数中不起作用?

class A:
    def __init__(self, x=0):
        print "constructing A"
        self.x = x

    def printx(self):
        print "x =",self.x 

class B(A):
    def __init__(self,x):
        A.__init__(self)
        print "constructing B"
        self = A(x)
        self.printx()


b = B(2)
b.printx()

输出:

constructing A
constructing B
constructing A
x = 2
x = 0

2 个答案:

答案 0 :(得分:2)

您不想在B.__init__中调用构造函数,并且应该将x传递给A.__init__

class A:
    def __init__(self, x=0):
        print "constructing A"
        self.x = x
    def printx(self):
        print "x =",self.x 

class B(A):
    def __init__(self,x):
        A.__init__(self, x)
        print "constructing B"
        self.printx()

答案 1 :(得分:1)

在Python中,将变量名称(如self)视为“指向”或“引用”值。当您创建B的实例时:

b = B(2)

调用B.__init__方法时,变量self已分配给B的早期实例。现在,在这个方法中,当Python到达

        self = A(x)

变量self被重新分配给A的新实例。 B的实例仍然存在; self不再指向它。

请注意,self是一个与Python中的任何其他变量一样的变量。 (self不是关键字,方法的第一个参数称为self只是一种惯例。)


顺便说一下,要使用self的值初始化x,请使用

class B(A):
    def __init__(self,x):
        A.__init__(self, x)    # <-- Note the x
        print "constructing B"
        self.printx()

然后

b = B(2)
b.printx()

产量

constructing A
constructing B
x = 2
x = 2

当一个类有一个替代构造函数,例如getA时,Python中的典型模式是使用类方法:

class A(object):
    def __init__(self, x=0):
        print "constructing A"
        self.x = x

    def printx(self):
        print "x =",self.x 

    @classmethod
    def getA(cls, x):
        print('constructing getA')
        self = cls(x)
        self.y = 1
        return self

现在用classmethod A创建getA的实例,你会说

a = A.getA(x)

A作为第一个参数传递给classmethod getA,并存储在变量cls中。

以这种方式做到这一点很有意义(而不是使用工厂函数getA),如果你像这样继承A

class B(A):
    def __init__(self,x):
        A.__init__(self, x)
        print "constructing B"
        self.printx()

然后您也可以使用B类方法创建getA的实例:

b = B.getA(2)

产量

constructing getA
constructing A
constructing B
x = 2

print(type(b))
print(b.y)

产量

<class '__main__.B'>  # b is an instance of B
1   # showing the y attribute has been set.