1、 super([type[, object-or-type]])

super() 在使用时至少传递一个参数,且这个参数必须是一个类。

通过super()获取到的是一个代理对象,通过这个对象去查找父类或者兄弟类的方法。

2、super()不写参数的情况

class Base:
def __init__(self):
print('Base.__init__') class A(Base):
def __init__(self):
super().__init__()
print('A.__init__') class B(Base):
def __init__(self):
super().__init__()
print('B.__init__') class C(Base):
def __init__(self):
super().__init__()
print('C.__init__') class D(A, B, C):
def __init__(self):
super().__init__() # 等同于 super(D, self).__init__()
print('D.__init__') D() print(D.mro())

结果:

Base.__init__
C.__init__
B.__init__
A.__init__
D.__init__
[<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>]

super() 在一个定义的类中使用时,可以不写参数,Python会自动根据情况将两个参数传递给super

在Python3中的类都是新式类,广度优先的查找顺序,在定义一个类时就会生成一个MRO列表(经典类没有MRO列表,深度优先),查找顺序就是按照这个列表中的类的顺序从左到右进行的。

3、super(type) 只传递一个参数的情况

class Base:
def __init__(self):
print('Base.__init__') class A(Base):
def __init__(self):
super().__init__()
print('A.__init__') class B(Base):
def __init__(self):
super().__init__()
print('B.__init__') class C(Base):
def __init__(self):
super().__init__()
print('C.__init__') class D(A, B, C):
def __init__(self):
super(B).__init__() # 值传递一个参数
print('D.__init__') D() print(D.mro())

结果:

D.__init__
[<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>]

其他方法都没有被调用。

super() 只传递一个参数时,是一个不绑定的对象,不绑定的话它的方法是不会有用的

4、super(type, obj) 传递一个类和一个对象的情况

class Base:
def __init__(self):
print('Base.__init__') class A(Base):
def __init__(self):
super().__init__()
print('A.__init__') class B(Base):
def __init__(self):
super().__init__()
print('B.__init__') class C(Base):
def __init__(self):
super().__init__()
print('C.__init__') class D(A, B, C):
def __init__(self):
super(B, self).__init__() # self是B的子类D的实例
print('D.__init__') D() print(D.mro())

结果:

Base.__init__
C.__init__
D.__init__
[<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>]

super() 的参数为一个类和一个对象的时候,得到的是一个绑定的super对象。但是obj必须是type的实例或者是子类的实例。

从结果可以看出,只是查找了B类之后的类的方法,

super()是根据第二个参数(obj)来计算MRO,根据顺序查找第一个参数(类)之后的类的方法

5、super(type1, type2) 传递两个类的情况

class Base:
def __init__(self):
print('Base.__init__') class A(Base):
def __init__(self):
super().__init__()
print('A.__init__') class B(Base):
def __init__(self):
super().__init__()
print('B.__init__') class C(Base):
def __init__(self):
super().__init__()
print('C.__init__') class D(A, B, C):
def __init__(self):
super(B, D).__init__(self) # D是B的子类,并且需要传递一个参数
print('D.__init__') D() print(D.mro())

结果:

Base.__init__
C.__init__
D.__init__
[<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>]

super()传递两个类type1和type2时,得到的也是一个绑定的super对象,但这需要type2是type1的子类,且如果调用的方法需要传递参数时,必须手动传入参数,因为super()第二个参数是类时,得到的方法是函数类型的,使用时不存在自动传参,第二个参数是对象时,得到的是绑定方法,可以自动传参。

结果:

最新文章

  1. android学习之线性布局
  2. Linux 文件基本属性
  3. 【汇总】iOS开发及Xcode使用中遇到的一些报错问题汇总
  4. Altium Designer10 如何导出Gerber文件
  5. 使用graphics2D给图片上画字符
  6. MySQL如何执行关联查询
  7. 使用 phpMailer 基于(SMTP) 发送邮件
  8. NGINX----源码阅读----(option配置脚本)
  9. linux进程管理和系统状态查看命令简介
  10. uploadify 3.2 java应用丢失session
  11. javaweb中上传图片并显示图片,用我要上传课程信息(里面包括照片)这个例子说明
  12. Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0/Ubuntu14.04(转)
  13. linux poi生成excel demo调试附调用代码
  14. Category Theory: 01 One Structured Family of Structures
  15. LINUX网络编程 IO 复用
  16. 【转载】WCF 客户端识别认证之UserName认证
  17. Office安装错误1402的解决
  18. P5282 【模板】快速阶乘算法(多项式运算+拉格朗日插值+倍增)
  19. ACM-ICPC 2018 徐州赛区网络预赛 G. Trace (set维护)
  20. Asp.Net 自定义 httpmodel 中间件 管道

热门文章

  1. Ceizenpok’s formula Gym - 100633J 扩展Lucas定理 + 中国剩余定理
  2. 实战:mysql写存储过程并定时调用
  3. C#入门笔记2 变量
  4. 向fedora添加rpmfusion源
  5. 随机不重复的取数组元素,并赋值给div使用
  6. Windows 10下mysql 64位 安装(mysql-5.7.11-winx64安装)
  7. 忘记Centos7.2下root用户密码后的处理方式
  8. 在使用线程池时应特别注意对ThreadLocal的使用
  9. [文章泛读] The varying faces of a program transformation systems (ACM Inroads, 2012)
  10. 洛谷 P1168 中位数