假设我有一些代码可以创建一个类:
class Item:
def __init__(self, param1):
do something with param1
现在假设我有一个对象ItemChild继承自该类并继承其初始化函数,即有一些代码调用Item的__init__
函数。但是,假设我还希望它在__init__
函数中执行更多操作,并且我希望它能够使用更多参数,即param1,param2,param3和param4。看起来父对__init__
函数的调用现在会混淆,因为当我将params 1-3传递给ItemChild的一个实例时,它不知道哪个参数是param1。有没有办法解决这个问题,或者是只限于该方法的初始化方法的继承并且无法扩展?
答案 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__()
方法都具有兼容的签名,否则您将获得例外。