提到super,最直接的想法就是它代表了父类,替父类执行某些方法。但是理解也仅止步于此,下面对super做进一步理解 super 的完整形式 常见的super用法如下 1 2 3 4 5 6 7 8 9 10 11 12 13 class
提到 super,最直接的想法就是它代表了父类,替父类执行某些方法。但是理解也仅止步于此,下面对 super做进一步理解 super 的完整形式常见的 super 用法如下
以上执行结果为 这个结果也符合理解,Male 继承了 Person,在初始化的时候执行了父类的初始化方法,也就继承了父类的 name 属性。 但是其实 super 的完整形式为
super 是一个类,其中第二个参数是个 class 或者 object,决定了使用怎样的 mro。第一个参数是个 class,决定了从 mro 哪个 class 后面的 class 开始寻找,并将函数绑定到第二个参数上。两个参数都是可选的。 本例中,self 就是 Male 的实例对象,于是 self 的 mro 就是 [Male,Person,Object],而第一个参数是 Male,于是就使用 Male 后面的 Person,发现 Person 有 __init__ 函数,于是就只执行 Person 的 __init__ 函数,也就是 super 行的语句等价于
执行结果同上 super 的使用super 可以在定义类之外的地方使用
执行结果为 可以看到 16 行报错了,报错的原因就是此时的 self 代表的是 Male 实例,Male 的 mro 是 Male,Person,Animal,Object。Male 在实例化的时候执行了父类的 __init__ 方法,而此时 super 的第一个参数是 Person,于是使用 Person 后面的 Animal,而 Animal 的 __init__ 方法只有一个参数,super 却传递了2个参数,于是报错了。正确地修改为
执行结果为 可以看到 Male 实例化的时候绕过了 Person,只输出了 Animal 和 Male。而在类之外执行的 super,执行了 Male 的父类(Person、Animal)的 __init__ 方法。 说明了 2 点:
再看一个例子将会更加明白 直觉上来说,D 的实例会执行父类的 say() ,首先会找到 B,于是会执行 B 的父类的 say(),于是会输出 'A'。结果却是 'C',原因就是 self 代表了 D 的实例,而 D 的 mro 是 ['B','C','A'],D 的实例执行父类的 say() ,会找到 B 执行 B 的 super 方法,相当于 super(B,self).say(),而此时的 self 代表 D,mro 搜索会选择 B 后面的 class 也就是 C,执行 C 的 say(),于是最终结果输出 'C' 类中使用 super 的时候,可以省略参数而直接写成 super(),这时 super 会将他所在的类当作第一个参数,将所在函数的第一个参数当作自己的第二个参数。显然,这样省略参数的 super 不能在类之外直接使用。 最后,查看一个类的 mro 可以用 class.__mro__ 或者 class.mro() 获取 |
2019-06-18
2019-07-04
2021-05-23
2021-05-27
2021-05-27