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

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

class MdiChild(QtGui.QTextEdit):
   sequenceNumber = 1

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

最佳答案 在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中添加了一个“hack”,因此对不带参数的super的调用等同于调用super(CurrentClass,self).这需要编译器中的一些更改.

以下是超级工作原理的简单示例:

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)表示:将代理带到对象实例,在那里我可以访问A的父进程. “父”由MRO定义:

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

在单继承的情况下,简单地说是层次结构中对象的类的名称,但是对于多重继承,树是线性化的,因此如果类A调用哪个方法变得更加复杂.

点赞