2013-01-08 68 views
0

比方说,我有一个创建一个类中的一些代码:添加到继承的初始化?

class Item: 
    def __init__(self, param1): 
     do something with param1 
现在

让我们说我有一个对象,ItemChild,从该类继承并继承了它的初始化函数,即有一些代码来调用项目的__init__功能。但是,假设我还希望它在__init__函数中做得更多,并且我希望它能够使用更多参数,即param1,param2,param3和param4。看起来像父母的__init__函数的调用现在会被混淆,因为当我将参数1-3传递给ItemChild的一个实例时,它不知道哪个参数是param1。有没有什么办法可以解决这个问题,还是仅限于该方法的初始化方法的继承,并且无法扩展?

回答

3

这里是处理这样的情况下正确的方法:

class Item(object): 
    def __init__(self, param1): 
     # do something with param1 

class ItemChild(Item): 
    def __init__(self, param1, param2, param3, param4): 
     super(ItemChild, self).__init__(param1) 
     # do something with params 

注意Itemobject继承是很重要的,因为super()只与新样式类的作品。

如注释中所述,使用3.x时,不需要包含参数到super(),您可以使用super().__init__(param1)

+1

注意在3.x中,你可以使用新的'super()',它有一些魔力,并且不需要参数。 –

2

不,只需根据需要将参数委托给孩子的__init__即可。

class Parent(object): 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

class Child(Parent): 
    def __init__(self, w, x, y, z): 
     Parent.__init__(self, x, y) 
     self.w = w 
     self.z = z 

p = Parent(1, 2) 
# p.x == 1 
# p.y == 2 
c = Child(1, 2, 3, 4) 
# c.w = 1 
# c.x = 2 
# c.y = 3 
# c.z = 4 

您也可以使用super,如其他示例中所述。对于大多数情况下,这主要是个人喜好的问题,但是当您开始设计更高级的课程时,差异就变得很重要。 super将在MRO订单中查找班级家长的__init__()方法,并在需要时调用合作。直接调用超类'__init__()方法牺牲了一些自动功能以实现显式控制。此外,在super中,您必须小心所有__init__()孩子发现的方法都具有兼容的签名,否则您将得到例外。

3

这将实际工作周围的其他方法 - ItemChild__init__方法将首先被调用,并且可以转发只什么是适当的Item

class Item: 
    def __init__(self, param1): 
     print "Item.__init__ doing something with param1" 
     # do something with param1 


class ItemChild(Item): 
    def __init__(self, param1, param2, param3): 
     print "Starting ItemChild.__init__" 
     super(ItemChild, self).__init__(param1) 
     print "ItemChild.__init__ doing something with params 2 and 3" 
     # do something with param2 and param3 

当你调用ItemChild(1, 2, 3)的流程如下: :

Starting ItemChild.__init__ 
Item.__init__ doing something with param1 
ItemChild.__init__ doing something with params 2 and 3 

不是:

Item.__init__ doing something with param1 
Starting ItemChild.__init__ 
ItemChild.__init__ doing something with params 2 and 3 

当然,您可以重新安排您的super调用,以便在您做其他事情之前或之后运行 - 或者如果您不想让父母的行为运行,则可以完全保留它。