super()的第二个参数?

Edv*_*olm 13 python class super python-3.x

我的一位同事今天写了类似下面的代码,请我看看,我花了一段时间才发现错误:

class A():                                                                                         
    def __init__(self):                                                         
        print('A')                                                              

class B(A):                                                                     
    def __init__(self):                                                         
        super(B).__init__()                                               

b = B()
Run Code Online (Sandbox Code Playgroud)

这里的问题是在构造函数中没有self参数.让我感到惊讶的是,在这种情况下绝对没有任何事情发生,即没有错误,没有.包含的对象创建了什么?作为一个对象,它显然有一个构造函数,所以这是被调用的,但该对象是如何与?相关的?特别是,为什么这个有效的代码并没有在某处抛出异常?是一个具有一些实际用途的对象,那会是什么?super()Bsupersuper(B)Bsuper(B)

Kas*_*mvd 5

导致所有这些含糊之处的唯一原因是"为什么obj = super(B).__init__()有效?".这是因为super(B).__self_class__返回None,在这种情况下,你正在调用像下面的None对象__init__,返回None:

In [40]: None.__init__()
Run Code Online (Sandbox Code Playgroud)

关于其他案例,您可以通过super在两种情况下调用's基本属性来简单地检查差异:

In [36]: class B(A):                                                                     
        def __init__(self):                                                         
                obj = super(B, self)
                print(obj.__class__)
                print(obj.__thisclass__)
                print(obj.__self_class__)
                print(obj.__self__)
   ....:         

In [37]: b = B()
<class 'super'>
<class '__main__.B'>
<class '__main__.B'>
<__main__.B object at 0x7f15a813f940>

In [38]: 

In [38]: class B(A):                                                                     
        def __init__(self):                                                         
                obj = super(B)
                print(obj.__class__)
                print(obj.__thisclass__)
                print(obj.__self_class__)
                print(obj.__self__)
   ....:         

In [39]: b = B()
<class 'super'>
<class '__main__.B'>
None
None
Run Code Online (Sandbox Code Playgroud)

对于其他内容,我建议您仔细阅读文档.https://docs.python.org/3/library/functions.html#super和Raymond Hettinger的这篇文章https://rhettinger.wordpress.com/2011/05/26/super-considered-super/.

此外,如果你想知道为什么super(B)不在课外工作,一般为什么在课堂上调用super()没有任何参数可以阅读这个综合答案由Martijn /sf/answers/1372641791/.

解决方案的简短描述:

正如@NathanVērzemnieks的评论中所提到的,您需要调用初始化程序一次才能使super()对象正常工作.原因在于super上述链接中解释的新对象的魔力.

In [1]: class A:
   ...:     def __init__(self):
   ...:         print("finally!")
   ...:

In [2]: class B(A):
   ...:     def __init__(self):
   ...:         sup = super(B)
   ...:         print("Before: {}".format(sup))
   ...:         sup.__init__()
   ...:         print("After: {}".format(sup))
   ...:         sup.__init__()
   ...:

In [3]: B()
Before: <super: <class 'B'>, NULL>
After: <super: <class 'B'>, <B object>>
finally!
Run Code Online (Sandbox Code Playgroud)