Mik*_*ike 330 python inheritance constructor class superclass
class A:
def __init__(self):
print("world")
class B(A):
def __init__(self):
print("hello")
B() # output: hello
Run Code Online (Sandbox Code Playgroud)
在我使用超级构造函数的所有其他语言中隐式调用.如何在Python中调用它?我希望,super(self)但这不起作用.
Ign*_*ams 320
super()在新式类中返回类似父类的对象:
class A(object):
def __init__(self):
print("world")
class B(A):
def __init__(self):
print("hello")
super(B, self).__init__()
B()
Run Code Online (Sandbox Code Playgroud)
Aid*_*mez 227
与其他答案一致,有多种方法可以调用超类方法(包括构造函数),但是在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__()
Run Code Online (Sandbox Code Playgroud)
Python的3.X
class A(object):
def __init__(self):
print("world")
class B(A):
def __init__(self):
print("hello")
super().__init__()
Run Code Online (Sandbox Code Playgroud)
super()现在相当于super(<containing classname>, self)按该文档.
Gab*_*abe 53
使用Python 2.x旧式类,它将是这样的:
class A:
def __init__(self):
print "world"
class B(A):
def __init__(self):
print "hello"
A.__init__(self)
Run Code Online (Sandbox Code Playgroud)
Dan*_*ach 32
一种方法是调用A的构造函数并self作为参数传递,如下所示:
class B(A):
def __init__(self):
A.__init__(self)
print "hello"
Run Code Online (Sandbox Code Playgroud)
这种风格的优点是它非常清晰.它调用A的构造函数.缺点是它不能很好地处理菱形继承,因为你最终可能会两次调用共享基类的构造函数.
另一种方法是使用super(),正如其他人所示.对于单继承,它与让您调用父的构造函数基本相同.
但是,super()在引擎盖下相当复杂,有时在多继承情况下可能是反直觉的.在正面,super()可用于处理菱形继承.如果你想知道super()所做的细节,那么我发现super()工作的最佳解释就在这里(虽然我不一定赞同那篇文章的观点).
Shi*_*hah 12
简答
super(DerivedClass, self).__init__()
Run Code Online (Sandbox Code Playgroud)
长答案
有什么作用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__()
Run Code Online (Sandbox Code Playgroud)
如果我忘记为 super 调用 init 怎么办?
构造函数 ( __new__) 在链中被调用(如在 C++ 和 Java 中)。创建实例后,仅__init__调用该实例的初始化程序 ( ),而没有任何指向其超类的隐式链。
仅添加一个带有参数的示例:
class B(A):
def __init__(self, x, y, z):
A.__init__(self, x, y)
Run Code Online (Sandbox Code Playgroud)
给定需要定义变量x,y,z的派生类B和需要定义x,y的超类A,您可以使用对当前子类实例的引用来调用超类A 的静态方法init(个体),然后是预期参数列表。