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

roc*_*ock 4 python inheritance class pyqt4

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

class MdiChild(QtGui.QTextEdit):
   sequenceNumber = 1

   def __init__(self):
      super(MdiChild, self).__init__()
Run Code Online (Sandbox Code Playgroud)

Bak*_*riu 5

在python3.3 +中,您不需要显式传递类名,您可以这样做:

super().__init__()
Run Code Online (Sandbox Code Playgroud)

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

super().setText('Hello')  # calls QLineEdit.setText
Run Code Online (Sandbox Code Playgroud)

在python <3.3中super是正常功能。没有什么特别的。这意味着它知道从哪个阶级它被调用,因此现在不能如何找到父类,而没有经过论证明确。另外,您可能想要执行以下操作:

super(QLineEdit, self).__init__()
Run Code Online (Sandbox Code Playgroud)

它将调用QLineEdit的父类__init__()(即祖父母__init__()函数)。

从python3.3开始,添加了“ hack”,因此,super不带参数的调用等同于call 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
Run Code Online (Sandbox Code Playgroud)

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

super(NameOfCurrentClass, self)
Run Code Online (Sandbox Code Playgroud)

例如:

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
Run Code Online (Sandbox Code Playgroud)

表达super(A, instance)手段:取的代理对象instance在哪里可以访问的方法A。“父”由MRO定义:

In [12]: MyGrandChild.__mro__
Out[12]: (__main__.MyGrandChild, __main__.MyChild, __main__.MyBase, builtins.object)
Run Code Online (Sandbox Code Playgroud)

在单继承的情况下,只是层次结构中类的名称,直到object,但在多继承的情况下,树被线性化,因此,如果要对类A进行调用,则猜测哪种方法变得更加复杂。