class A:
def __init__(self):
print("world")
class B(A):
def __init__(self):
print("hello")
B() # output: hello
在我使用超级构造函数的所有其他语言中隐式调用。如何在Python中调用它?我希望super(self)
但这不起作用。
答案 0 :(得分:291)
super()
在新式类中返回类似父类的对象:
class A(object):
def __init__(self):
print "world"
class B(A):
def __init__(self):
print "hello"
super(B, self).__init__()
B()
答案 1 :(得分:190)
与其他答案一致,有多种方法可以调用超类方法(包括构造函数),但是在Python-3.x中,这个过程已经简化了:
<强> Python的2.x的强>
class A(object):
def __init__(self):
print "world"
class B(A):
def __init__(self):
print "hello"
super(B, self).__init__()
<强> Python的3.x的强>
class A(object):
def __init__(self):
print("world")
class B(A):
def __init__(self):
print("hello")
super().__init__()
根据{{3}}, super()
现在相当于super(<containing classname>, self)
。
答案 2 :(得分:51)
使用Python 2.x旧式类,它将是:
class A:
def __init__(self):
print "world"
class B(A):
def __init__(self):
print "hello"
A.__init__(self)
答案 3 :(得分:32)
一种方法是调用A的构造函数并将self
作为参数传递,如下所示:
class B(A):
def __init__(self):
A.__init__(self)
print "hello"
这种风格的优点在于它非常清晰。它叫A的初始化者。缺点是它不能很好地处理菱形继承,因为你最终可能会两次调用共享基类的初始值。
另一种方法是使用super(),正如其他人所示。对于单继承,它与让您调用父级的初始化器基本相同。
然而,super()在引擎盖下相当复杂,有时在多继承情况下可能会违反直觉。在正面,super()可用于处理菱形继承。如果你想知道super()的含义,我发现super()的工作原理的最佳解释是here(虽然我不一定赞同那篇文章的意见)。
答案 4 :(得分:5)
只需添加一个带有参数的示例:
class B(A):
def __init__(self, x, y, z):
A.__init__(self, x, y)
鉴于需要定义变量x,y,z的派生类B和需要定义x,y的超类A,您可以调用静态方法的 init 超类A,其中引用了当前子类实例(自身),然后是预期参数的列表。
答案 5 :(得分:2)
简短回答
super(DerivedClass, self).__init__()
长期回答
super()
做什么?
它采用指定的类名,找到其基类(Python允许多重继承),并从左到右在每个方法中寻找方法(在这种情况下为__init__
)。找到可用的方法后,它将立即调用它并结束搜索。
如何调用所有基类的init?
如果您只有一个基类,则可以使用上述方法。但是Python确实允许多重继承,您可能要确保所有基类都已正确初始化。为此,您应该使每个基类都调用init:
class Base1:
def __init__():
super(Base1, self).__init__()
class Base2:
def __init__():
super(Base2, self).__init__()
class Derived(Base1, Base2):
def __init__():
super(Derived, self).__init__()
如果我忘记为超级调用init了怎么办?
构造函数(__new__
)在链中被调用(如C ++和Java)。创建实例后,仅调用该实例的初始化程序(__init__
),而没有指向其超类的任何隐式链。
答案 6 :(得分:1)
我使用以下公式扩展了之前的答案:
class A(object):
def __init__(self):
print "world"
class B(A):
def __init__(self):
print "hello"
super(self.__class__, self).__init__()
B()
这样您就不必在 super 的调用中重复该类的名称。如果您编写大量类,并希望使用与类名无关的初始化方法中的代码,它可以派上用场。