PyQt4:为什么我们需要在调用super()时传递类名

时间:2014-03-30 12:39:36

标签: python class inheritance pyqt4

如下面的代码super(MdiChild, self).__init__(),我们在超级函数中传递mdichild。请解释为什么以及为什么使用.__init__()

class MdiChild(QtGui.QTextEdit):
   sequenceNumber = 1

   def __init__(self):
      super(MdiChild, self).__init__()

2 个答案:

答案 0 :(得分:2)

在python3.3 +中你需要明确传递类名,你可以这样做:

super().__init__()

现在,请注意super 调用构造函数。它只是提供了一个对象,您可以在其中访问给定实例的属性,就好像它是父类的实例一样。例如,您可以拨打setText

super().setText('Hello')  # calls QLineEdit.setText

在python< 3.3 super中是一个正常的函数。它没有什么特别之处。这意味着它知道从哪个类调用它,因此它现在不能如何在不显式传递参数的情况下找到父类。你也可以做以下事情:

super(QLineEdit, self).__init__()

哪个会调用QLineEdit的父类__init__()(即祖父__init__()函数)。

来自python3.3 a" hack"添加,以便不带参数的super调用等同于调用super(CurrentClass, self)。这需要在编译器中进行一些更改。


以下是super如何运作的简单示例:

In [1]: class MyBase(object):
   ...:     def __init__(self):
   ...:         print('MyBase.__init__() called')

In [2]: class MyChild(MyBase):
   ...:     def __init__(self):
   ...:         print('MyChild.__init__() called')
   ...:         super().__init__() # MyBase.__init__
   ...:         

In [3]: class MyGrandChild(MyChild):
   ...:     def __init__(self):
   ...:         print('MyGrandChild.__init__() called')
   ...:         super().__init__()  # MyChild.__init__
   ...:         print('Between super calls')
   ...:         super(MyChild, self).__init__()  # MyBase.__init__
   ...:         super(MyBase, self).__init__() # object.__init__ (does nothing)

In [4]: MyGrandChild()
MyGrandChild.__init__() called
MyChild.__init__() called
MyBase.__init__() called
Between super calls
MyBase.__init__() called

在python< 3.3中,你不能省略类名,每次调用不带参数的super()都必须替换为:

super(NameOfCurrentClass, self)

例如:

In [7]: class MyBase(object):
   ...:     def __init__(self):
   ...:         print('MyBase.__init__() called')

In [8]: class MyChild(MyBase):
   ...:     def __init__(self):
   ...:         print('MyChild.__init__() called')
   ...:         super(MyChild, self).__init__()

In [9]: class MyGrandChild(MyChild):
   ...:     def __init__(self):
   ...:         print('MyGrandChild.__init__() called')
   ...:         super(MyGrandChild, self).__init__()
   ...:         print('Between super calls')
   ...:         super(MyChild, self).__init__()
   ...:         super(MyBase, self).__init__()

In [10]: MyGrandChild()
MyGrandChild.__init__() called
MyChild.__init__() called
MyBase.__init__() called
Between super calls
MyBase.__init__() called

表达式super(A, instance)表示:将代理转到对象instance,我可以在其中访问A 的方法。 "父母"由MRO

定义
In [12]: MyGrandChild.__mro__
Out[12]: (__main__.MyGrandChild, __main__.MyChild, __main__.MyBase, builtins.object)

在单继承的情况下,只是层次结构中类的名称,直到object,但是具有多重继承,树被线性化,因此如果类A那么调用哪个方法变得更复杂猜猜。

答案 1 :(得分:0)

考虑来自C的{​​{1}}继承和B的{​​{1}}继承,并创建B类型的对象A

fooC,即foo.__init__()。但是,由于对象属于C.__init__()类型,如果B.__init__未指定它想要调用C的父B.__init__(即。B),它将调用自身(即__init__),因为A.__init__是对象的父类。

不确定我是否清楚,我希望有所帮助。

相关问题