当前位置: 首页 > news >正文

建湖网站建设/建站开发

建湖网站建设,建站开发,用织梦做网站有什么公司会要,计算机学什么专业比较好Python多继承与super使用详解 原创牛大财有大才 最后发布于2018-08-17 12:51:38 阅读数 13409 收藏 展开 Python虽然支持多继承,但是python支持的多继承也是有限的。 0.问题的提出 如果不同的父类中存在 同名的方法,子类对象在调用方法时,会…

Python多继承与super使用详解
原创牛大财有大才 最后发布于2018-08-17 12:51:38 阅读数 13409  收藏
展开
Python虽然支持多继承,但是python支持的多继承也是有限的。

0.问题的提出
如果不同的父类中存在 同名的方法,子类对象在调用方法时,会调用哪一个父类中的方法呢?
Python 中的 MRO —— 方法搜索顺序

Python 中针对 类 提供了一个内置属性 __mro__ 可以查看方法搜索顺序
MRO 是 method resolution order,主要用于在多继承时判断 方法、属性 的调用 路径
print(C.__mro__)  #C是多继承后的类名
输出结果

(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
在搜索方法时,是按照 __mro__ 的输出结果 从左至右 的顺序查找的
如果在当前类中 找到方法,就直接执行,不再搜索
如果 没有找到,就查找下一个类 中是否有对应的方法,如果找到,就直接执行,不再搜索
如果找到最后一个类,还没有找到方法,程序报错
1.多继承的使用
#1.多继承:子类有多个父类
 
class Human:
    def __init__(self, sex):
        self.sex = sex
 
    def p(self):
        print("这是Human的方法")
 
 
class Person:
    def __init__(self, name):
        self.name = name
 
    def p(self):
        print("这是Person的方法")
 
    def person(self):
        print("这是我person特有的方法")
 
 
class Teacher(Person):
    def __init__(self, name, age):
        super().__init__(name)
        self.age = age
 
 
class Student(Human, Person):
    def __init__(self, name, sex, grade):
    #要想调用特定父类的构造器可以使用父类名.__init__方式。多继承使用super,会有一个坑,具体参考后面
       Human.__init__(self,sex)
       Person.__init__(self,name)
       self.grade = grade
 
 
class Son(Human, Teacher):
    def __init__(self, sex, name, age, fan):
        Human.__init__(self, sex)
        Teacher.__init__(self, name, age)
        self.fan = fan
 
 
# ------创建对象 -------------
stu = Student("tom", "male", 88)
print(stu.name,stu.sex,stu.grade)
stu.p()  # 虽然父类Human和Person都有同名P()方法 ,但是调用的是括号里的第一个父类Human的方法
 
 
son1 = Son("jerry", "female", 18, "打球")
son1.person()  # 可以调用父类的父类的方法。
son1.p()  # 子类调用众多父类中同名的方法,按继承的顺序查找。
=====================================================================================
tom male 88
这是Human的方法
这是我person特有的方法
这是Human的方法
总结:1.需要注意圆括号中继承父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。

           2.支持多层父类继承,子类会继承父类所有的属性和方法,包括父类的父类的所有属性 和 方法。

2.多继承的使用注意事项     
#1.多继承子类对父类构造方法的调用
class Human:
    def __init__(self,sex):
        self.sex = sex
    def p(self):
        print("这是Human的方法")
    def str1(self):
        print("this si"+str(self.sex))
 
class Person:
    def __init__(self,name):
        self.name = name
    def p(self):
        print("这是Person的方法")
    def person(self):
        print("这是我person特有的方法")
 
    def str2(self):
        print( "this is:" + str(self.name))
 
class Student(Human,Person): #注意子类如果没有构造方法时,按括号内父类的继承顺序去继承父类构造方法,只继承一个
    def prin(self):
        print("student")
#------创建对象 -------------
#stu1=Studnent("男","tom")报错。
stu = Student("sex") #这里继承的是Huma的构造方法。
stu.p()
stu.str1() 
#stu.str2()报错,因为即使human和person都是一个参数的构造方法,但是这里继承调用的是第一个Human的构造方法
====================================================================================
这是Human的方法
this sisex
  总结:子类从多个父类派生,而子类又没有自己的构造函数时,

(1)按顺序继承,哪个父类在最前面且它又有自己的构造函数,就继承它的构造函数;

(2)如果最前面第一个父类没有构造函数,则继承第2个的构造函数,第2个没有的话,再往后找,以此类推。

3.多继承时使用super调用父类属性方法的注意事项
3.1不使用super调用父类方法,使用父类名.方法名的形式。

class Parent(object):
    def __init__(self, name):
        print('parent的init开始被调用')
        self.name = name
        print('parent的init结束被调用')
 
class Son1(Parent):
    def __init__(self, name, age):
        print('Son1的init开始被调用')
        self.age = age
        Parent.__init__(self, name) #直接使用父类名.方法名的方式调用父类的__init__方法
        print('Son1的init结束被调用')
 
class Son2(Parent):
    def __init__(self, name, gender):
        print('Son2的init开始被调用')
        self.gender = gender
        Parent.__init__(self, name) #
        print('Son2的init结束被调用')
 
class Grandson(Son1, Son2):
    def __init__(self, name, age, gender):
        print('Grandson的init开始被调用')
        Son1.__init__(self, name, age)  # 单独调用父类的初始化方法
        Son2.__init__(self, name, gender)
        print('Grandson的init结束被调用')
 
gs = Grandson('grandson', 12, '男') 
print('姓名:', gs.name)
print('年龄:', gs.age)
print('性别:', gs.gender)
 
'''执行结果如下:
Grandson的init开始被调用
Son1的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son1的init结束被调用
Son2的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
Grandson的init结束被调用
姓名: grandson
年龄: 12
性别: 男
'''
注意:上面代码里当在子类中通过父类名调用时,parent被执行了2次

3.2 使用super调用父类中的方法,注意分析程序的执行顺序。

class Parent(object):
    def __init__(self, name, *args, **kwargs):  # 为避免多继承报错,使用不定长参数,接受参数
        print('parent的init开始被调用')
        self.name = name
        print('parent的init结束被调用')
 
class Son1(Parent):
    def __init__(self, name, age, *args, **kwargs):  # 为避免多继承报错,使用不定长参数,接受参数
        print('Son1的init开始被调用')
        self.age = age
        super().__init__(name, *args, **kwargs)  # 为避免多继承报错,使用不定长参数,接受参数
        print('Son1的init结束被调用')
 
class Son2(Parent):
    def __init__(self, name, gender, *args, **kwargs):  # 为避免多继承报错,使用不定长参数,接受参数
        print('Son2的init开始被调用')
        self.gender = gender
        super().__init__(name, *args, **kwargs)  # 为避免多继承报错,使用不定长参数,接受参数
        print('Son2的init结束被调用')
 
class Grandson(Son1, Son2):
    def __init__(self, name, age, gender):
        print('Grandson的init开始被调用')
        # 多继承时,相对于使用类名.__init__方法,要把每个父类全部写一遍
        # 而super只用一句话,执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因
        # super(Grandson, self).__init__(name, age, gender) 效果和下面的一样
        super().__init__(name, age, gender)
        print('Grandson的init结束被调用')
 
print(Grandson.__mro__) #搜索顺序
 
gs = Grandson('grandson', 12, '男')
 
print('姓名:', gs.name)
print('年龄:', gs.age)
print('性别:', gs.gender)
 
'''结果如下:
(<class '__main__.Grandson'>, <class '__main__.Son1'>, <class '__main__.Son2'>, <class '__main__.Parent'>, <class 'object'>)
Grandson的init开始被调用
Son1的init开始被调用
Son2的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
Son1的init结束被调用
Grandson的init结束被调用
姓名: grandson
年龄: 12
性别: 男
'''
 注意:在上面模块中,当在子类中通过super调用父类方法时,parent被执行了1次。

super调用过程:上面gs初始化时,先执行grandson中init方法, 其中的init有super调用,每执行到一次super时,都会从__mro__方法元组中顺序查找搜索。所以先调用son1的init方法,在son1中又有super调用,这个时候就就根据__mro__表去调用son2的init,然后在son2中又有super调用,这个就根据mro表又去调用parent中的init,直到调用object中的init.  所以上面的打印结果如此,要仔细分析执行过程。

尖叫提示:
 super().__init__相对于类名.__init__,在单继承上用法基本无差
但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次,具体看前面的输出结果
多继承时,使用super方法,对父类的传参数,应该是由于python中super的算法导致的原因,必须把参数全部传递,否则会报错
单继承时,使用super方法,则不能全部传递,只能传父类方法所需的参数,否则会报错
多继承时,相对于使用类名.__init__方法,要把每个父类全部写一遍, 而使用super方法,只需写一句话便执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因
3.3单继承使用super调用父类方法

class Parent(object):
    def __init__(self, name):
        print('parent的init开始被调用')
        self.name = name
        print('parent的init结束被调用')
 
class Son1(Parent):
    def __init__(self, name, age):
        print('Son1的init开始被调用')
        self.age = age
        super().__init__(name)  # 单继承不能提供全部参数
        print('Son1的init结束被调用')
 
class Grandson(Son1):
    def __init__(self, name, age, gender):
        print('Grandson的init开始被调用')
        super().__init__(name, age)  # 单继承不能提供全部参数
        print('Grandson的init结束被调用')
 
gs = Grandson('grandson', 12, '男')
print('姓名:', gs.name)
print('年龄:', gs.age)
统一声明:关于原创博客内容,可能会有部分内容参考自互联网,如有原创链接会声明引用;如找不到原创链接,在此声明如有侵权请联系删除哈。关于转载博客,如有原创链接会声明;如找不到原创链接,在此声明如有侵权请联系删除哈。
————————————————
版权声明:本文为CSDN博主「牛大财有大才」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_26442553/article/details/81775449

http://www.lbrq.cn/news/1477981.html

相关文章:

  • 博山政府网站建设哪家好/网址搜索引擎入口
  • 深圳培训网站开发/推广app的软文案例
  • o2o网站建设咨询/pr的选择应该优先选择的链接为
  • fifa17做任务网站/常州谷歌推广
  • 铜川市建设集团网站/有什么引流客源的软件
  • 文化建设ppt/seo网站关键词排名软件
  • 新型城镇化建设网站/成都网站建设方案外包
  • 网站域名批量查询注册/广东vs北京首钢
  • 四川建设网站项目招标/seo优化网络公司排名
  • 兴义做网站的/广州百度seo公司
  • 手机app开发语言/推推蛙seo
  • 万户网络是干什么的/合肥网站推广优化
  • 肇庆网站快速排名优化/网络营销的策划流程
  • 北京企业名录一览表/怀柔网站整站优化公司
  • 中山免费企业网站建设/郑州推广优化公司
  • 在猪八戒网站如何做兼职/杭州seook优屏网络
  • 制作测试的网站/广州网站开发多少钱
  • 做网站和网站页面设计/职业技能培训网上平台
  • iis做的网站如何添加播放器/seo搜索引擎优化到底是什么
  • 曲阜网站建设/东莞市网络seo推广服务机构
  • 香港可以做违法网站吗/seo网站推广经理
  • 网站建设策划怎么沟通/百度收录提交入口地址
  • 大连网站程序开发/百度图片搜索引擎
  • 深圳定制网站制作招聘网/网络营销推广平台有哪些
  • 名字做藏头诗的网站/网站建设需要多少钱?
  • 政府网站集约化建设十分重要/重庆百度seo整站优化
  • 学习做网站只学过c/免费发布活动的平台
  • 上海网站建设的价格低/专业软文发布平台
  • 润州网站建设/铁力seo
  • 新疆网站建设一条龙服务/seo实战培训视频
  • sqli-labs:Less-18关卡详细解析
  • 关于Web前端安全防御CSRF攻防的几点考虑
  • 理解HTTP协议
  • Linux选择
  • 逻辑回归----银行贷款模型优化
  • Ubuntu 系统下使用 lsusb 命令识别 USB 设备及端口类型详解