python - super() 的第二个参数?

标签 python python-3.x class super

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

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

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

b = B()

这里的问题是B 的构造函数中super() 没有self 参数。令我惊讶的是,在这种情况下绝对没有发生任何事情,即没有错误,什么也没有。 super(B) 创建的super 对象包含什么?作为一个对象,它显然有一个构造函数,所以它就是被调用的东西,但是那个对象与 B 有什么关系?特别是,为什么这个有效代码没有在某处抛出异常? super(B) 是一个有实际用途的对象吗?

最佳答案

唯一导致所有这些歧义的是“为什么 obj = super(B).__init__() 有效?”。那是因为 super(B).__self_class__ 返回 None 并且在这种情况下你正在调用 None 对象的 __init__ 像下面这样返回 None:

In [40]: None.__init__()

关于其余情况,您可以通过在这两种情况下调用super 的基本属性来简单地检查差异:

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

对于其余的事情,我建议您通读文档。 https://docs.python.org/3/library/functions.html#super和 Raymond Hettinger 的这篇文章 https://rhettinger.wordpress.com/2011/05/26/super-considered-super/ .

此外,如果您想知道为什么 super(B) 在类外不起作用,以及通常为什么不带任何参数调用 super() 在类内起作用您可以阅读的类(class) Martijn 的综合回答https://stackoverflow.com/a/19609168/2867928 .

解决方案的简短描述:

正如@Nathan Vē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!

关于python - super() 的第二个参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48302139/

相关文章:

python - 如何解决函数问题同时允许其动态化?

python - 等待任何 future 的异步

javascript - 为什么需要通过实例访问原型(prototype)?

java - 编译时出现错误 : class, 接口(interface)或预期枚举

python - 有没有在python中应用的实现

python - Mac OS 上的 ibm_boto3 与 scikit-learn 的兼容性问题

python - 通过多标签分类应用和绘制数据

python - 如何使用 webbrowser 模块在 python 3 中打开网站但在后台?

python - 使用 "yield from"表达式时 return 有什么作用?

java - 为什么这个类有两个构造函数?