2012-11-21 36 views
0

我有两个类:基类A和派生类B.在B的构造函数中,我尝试使用A的构造函数初始化实例。为什么在派生类的构造函数中赋值“self = A(x)”不起作用?python类继承︰派生类的构造函数问题

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 
+1

究竟是你想怎么办?即你的预期产出是什么? –

回答

1

在Python,认为变量名(如self)为 “指着” 或 “参考” 的值。当您的B一个实例:

b = B(2) 

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

 self = A(x) 

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

请注意,self是一个类似于Python中的其他变量。 (self不是关键字,它只是一个约定的方法的第一个参数叫self


顺便说一句,与x值初始化self,使用

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 

现在做的A实例与类方法getA,你倒是说

a = A.getA(x) 

A被作为第一个参数的类方法getA,和STOR传递编辑变量cls

什么是美丽大约做这种方式(而不是使用工厂函数getA)是,如果你继承A这样的:

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

那么你可以使用getA类方法是使B实例好:

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. 
+0

谢谢@unutbu和@jfaller!那么 - 如何将一个值赋给'self'而不将其重新分配给一个新的A实例?我问的原因是我有一个'工厂'函数'getA(x)'返回A类型的对象。有什么办法可以在B的构造函数中使用类似'self = getA(x)'的东西? – Misha

+0

不要尝试重新分配'self'。相反,想想如何修改'self'(改变它的属性)。我编辑了我的帖子以显示一种方法。 – unutbu

+0

非常感谢!这非常有帮助。 – Misha

2

你不想调用构造函数B.__init__,你应该通过xA.__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()