浅析:python多继承中三个重写父类方法的方式

前言

  • 该文大白话解释,如不专业,请多包涵。
  • 调用父类方法有三种方式:
    1、类名.方法(self)    # 此处没有代码说明,在文末有益于理解的文字说明(不推荐)
    2、super().方法名   # 和下面一种调用方法一样(常用)
    3、super(类名,self).方法名
    ps:为什么要有self这个参数?仅供参考的理解是:将自己作为实参传递给这个继承的类中,才能执行对应方法的代码。

  • 类名.__mro__是依照C3算法衍生出来的一个类的属性,该属性的特点是:
    1、使所有继承的类只执行一次。
    2、返回一个元祖,元祖中是使用super()方法时调用父类方法的顺序。(顺序是:拿着类名去元祖里面找,找到了之后,便去执行它的“下一个”对应的类中对应的方法
  • 总的来说,py2继承顺序是深度优先,py3是广度优先,关于深度优先和广度优先请相关链接:链接一   链接2   链接3

代码1
class P(object):
    def __init__(self):
        print("---测试---\r\n")


class S1(P):
    def __init__(self):
        print("--开始S1--")
        # super().__init__() # 默认是自己的类名,所以等同super(S2, self).__init__()
        super(S1, self).__init__()


print("我是S1的__mro__:", S1.__mro__)
a = S1()


# todo 输出为:
# 我是S1的__mro__: (<class '__main__.S1'>, <class '__main__.P'>, <class 'object'>)
# # --开始S1--
# # ---测试---

代码2

class P(object):
    def __init__(self):
        print("---测试---\r\n")


class S1(P):
    def __init__(self):
        print("--开始S1--")
        # super().__init__()
        super(S1, self).__init__()


class S2(S1):
    def __init__(self):
        print("--开始S2--")
        # super().__init__()  # 默认是自己的类名,所以等同super(S2, self).__init__()
        super(S2, self).__init__()  # 根据__mro__,它会去执行S1中的__init__()。
        super(S1, self).__init__()  # 根据__mro__,它会去执行P中的__init__(),所以没有了  "--开始S1--"。
        super(P, self).__init__()  # 执行了,但是执行的是  <class 'object'> 所以没数据。


print("我是S1的__mro__:", S1.__mro__)
print("我是S2的__mro__:", S2.__mro__,"\r\n")


a = S1()
b = S2()

# todo 输入为:
# 我是S1的__mro__: (<class '__main__.S1'>, <class '__main__.P'>, <class 'object'>)
# 我是S2的__mro__: (<class '__main__.S2'>, <class '__main__.S1'>, <class '__main__.P'>, <class 'object'>)
#
# --开始S1--
# ---测试---
#
# --开始S2--
# --开始S1--
# ---测试---
#
# ---测试---

补充

  • 重写不等于重载,关于重载在python中是极少的,可以忽略不记(比如运算符 ‘+’ 是用了重载)。重载是什么?简单理解:对于一个相同的变量名的函数,传入不同数据类型的参数,可以精确的调用该函数进行操作的过程。
  • 多继承中的“类名.方法”的方式在此文没有解释。为什么呢?
    1、python3基本上要把它淘汰了。
    2、为什么要淘汰?:它的机制你可以理解为:如果“孙子”类有俩“爸爸”类,他的两个“爸爸”类在自己的某一个方法中方法中都调用了“爷爷”类的那个方法,当调用两个“爸爸”类中的这个方法时,而于是就造成了爷爷的代码被调用了多次。一方面太冗余,另一方面可能出现不必要的bug,而如果使用的是super()方式的话,会按照__mro__属性的顺序来调用,就不存在这方面的问题。所以类名.的方式不推荐使用
  • python2的深度优先的弊端是什么?
    • 爸爸辈们的方法还没执行呢,直接执行了爷爷辈,这合适吗?
  • 此文只写到“儿子”辈儿,其实写到“孙子”辈儿就可以理解的更透彻了,但是本文旨在通俗理解多继承中的一些坑,如果想要更全面的了解的话,可以自己写一下代码,或者参考一下别人的博文。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值