添加继承初始化?

时间:2013-01-08 22:04:02

标签: python

假设我有一些代码可以创建一个类:

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

现在假设我有一个对象ItemChild继承自该类并继承其初始化函数,即有一些代码调用Item的__init__函数。但是,假设我还希望它在__init__函数中执行更多操作,并且我希望它能够使用更多参数,即param1,param2,param3和param4。看起来父对__init__函数的调用现在会混淆,因为当我将params 1-3传递给ItemChild的一个实例时,它不知道哪个参数是param1。有没有办法解决这个问题,或者是只限于该方法的初始化方法的继承并且无法扩展?

3 个答案:

答案 0 :(得分:3)

它实际上会以相反的方式工作 - ItemChild的{​​{1}}方法将首先被调用,并且只能转发适合__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 来电,以便在您执行其他操作之前或之后运行 - 或者如果您不想让父母的行为运行,您可以将其完全排除。< / p>

答案 1 :(得分: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

请注意,从Item继承的object非常重要,因为super()仅适用于新式类。

如评论中所述,使用3.x您不需要将参数包含在super()中,您只需使用super().__init__(param1)

答案 2 :(得分: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__()方法都具有兼容的签名,否则您将获得例外。