How to invoke the super constructor?
1 2 3 4 5 6 7 8 9 | class A: def __init__(self): print("world") class B(A): def __init__(self): print("hello") B() # output: hello |
在我使用过的所有其他语言中,都隐式地调用了超级构造函数。如何在Python中调用它?我想是
1 2 3 4 5 6 7 8 9 10 | class A(object): def __init__(self): print"world" class B(A): def __init__(self): print"hello" super(B, self).__init__() B() |
与其他答案一致,有多种方法可以调用超级类方法(包括构造函数),但是在python-3.x中,过程被简化了:
Python 2.x
1 2 3 4 5 6 7 8 | class A(object): def __init__(self): print"world" class B(A): def __init__(self): print"hello" super(B, self).__init__() |
Python 3.x
1 2 3 4 5 6 7 8 | class A(object): def __init__(self): print("world") class B(A): def __init__(self): print("hello") super().__init__() |
根据文件,
对于python 2.x旧样式类,应该是:
1 2 3 4 5 6 7 8 | class A: def __init__(self): print"world" class B(A): def __init__(self): print"hello" A.__init__(self) |
一种方法是调用的构造函数并将
1 2 3 4 | class B(A): def __init__(self): A.__init__(self) print"hello" |
这种风格的优点是它非常清晰。它称为的构造函数。缺点是它不能很好地处理菱形继承,因为最终可能会两次调用共享基类的构造函数。
另一种方法是使用super(),如其他人所示。对于单个继承,它基本上与允许您调用父级的构造函数相同。
然而,super()在引擎盖下要复杂得多,并且有时在多个继承情况下可能是反直觉的。另一方面,super()可以用来处理菱形继承。如果你想知道super()的具体功能,我找到的关于super()工作原理的最好解释就在这里(尽管我不一定赞同那篇文章的观点)。
简短回答
1 | super(DerivedClass, self).__init__() |
长回答
它使用指定的类名,查找其基类(python允许多重继承),并从左到右在每个类中查找方法(本例中为
如何调用所有基类的init?
如果您只有一个基类,那么上面的方法是有效的。但python允许多个继承,您可能希望确保所有基类都正确初始化。为此,您应该让每个基类调用init:
1 2 3 4 5 6 7 8 9 10 11 | 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__() |
如果我忘记为super调用init怎么办?
没有调用基类的
我使用以下公式扩展以前的答案:
1 2 3 4 5 6 7 8 9 10 | class A(object): def __init__(self): print"world" class B(A): def __init__(self): print"hello" super(self.__class__, self).__init__() B() |
这样就不必在调用super时重复类的名称。如果您要对大量类进行编码,并且希望使构造函数方法中的代码独立于类名,那么它就可以派上用场。