python多继承父类参数问题,python 继承多个父类
虽然python支持多重继承,但是Python支持的多重继承是有限的。
0.问题的提出如果不同的父类中存在同名的方法,子类对象调用方法时会调用哪一个父类中的方法?Python 中的 MRO —— 方法搜索顺序
Python为类提供了一个内置属性_ _ MRO _ _。可以查看方法搜索顺序。MRO是方法解析顺序,主要用于在多继承时判断 方法、属性 的调用 路径print(C.__mro__) #C是多重继承后的类名输出结果。
(class _ _ main _ _。c ,class _ _ main _ _。a ,class _ _ main _ _。b ,class object )搜索方法时,按照__mro__从左至右输出结果的顺序查找。如果当前类中有对应的方法找到方法,就直接执行,不再搜索,没有找到,就查找下一个类。如果找到了最后一个类,但是没有找到方法,程序错误1。多重继承的使用#1。多重继承:一个子类有多个父类ClassHuman: def _ _ init _ _ (self,sex):self . sex=sex def p(self):print(这是人类的方法)class Person: def __init__(self,Name): self。name=name def p (self): print(这是人的方法)def person(self): print(这是我独有的人的方法)班主任(person): def _ _ init _ _ (self,name,Age): super()。_ _ init _ _(name)self . age=ageclassstudent(human,person): def _ _ init _ _ (self,name,sex,grade): #可以使用父类名。_ _ init _ _调用特定父类的构造函数。继承使用超,会有坑。详情可参考以下人类。_ _ init _ _(自我,性)人。_ _ init _ _(自身,名称)自身。Grade=GradeClassson(人类,老师):def _ _ init _ _(本人,性别,姓名,年龄,粉丝):人类。_ _ init _ _(自我,性)老师。_ _ init _ _ (self,name,age)self . fan=fan #-stu=student 88)print(stu . name,stu.sex,stu.grade) stu.p () #虽然父类Human和Person都有同名的p()方法,但是括号中第一个父类Human的方法叫做son1=Son(兴奋的大叔,女,18,打球。son1.p() #子类调用许多父类中同名的方法,并按继承顺序查找它们。===================================================================
如果找到,就直接执行,不再搜索
总结:1.需要注意圆括号中继承父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。# 1.多继承子类对父类构造函数类Human: def __init__(self,Sex):self . Sex=Sex def p(self):print(这是人类的方法)def str 1(self):print( This si str(self . Sex))类person: def _ _ init _ _ (self,Name): self。name=name def p (self): print(这是人的方法)def person(self): print(这是我独有的人的方法)def str2 (self): print(这是: str (self。name) ) class Student(Human,Person): #注意,如果子类没有构造函数,则按照括号中父类的继承顺序继承父类的构造函数,只继承一个defprin(self):print( Student )#-# stu 1。Stu=Student(性)#呼玛的构造方法在这里继承。Stu.p()stu.str1() #stu.str2()报错,因为虽然human和person都是一个参数的构造方法,但是这里是第一个人的构造方法================================
2.支持多层父类继承,子类会继承父类所有的属性和方法,包括父类的父类的所有属性 和 方法。
2.多继承的使用注意事项
总结:子类从多个父类派生,而子类又没有自己的构造函数时,
class Parent(object):def _ _ init _ _(self,Name): print(parent的init开始被调用)self.name=name print(parent的init结束被调用)class son 1(Parent):def _ _ init _ _(self,Name,Age):print( son 1的init开始被调用)self.age=ageparent。_ _ init _ _ (self,Name) #调用父类的_ _ init _ _方法print( son 1的init端被调用)class son 2(parent):def _ _ init _ _(self,Name,Gender): print(Son2的init开始被调用)self.gender=genderparent。_ _ init _ _ (self,name) # print (son2的init结束被调用)类孙子(Son1,2): def _ _ init _ _ (self,name,age,gender): print(孙子的init开始被调用)Son1。__init__(self,name,age) #调用初始化方法Son2。__init__(self,name,Gender) print(孙子的init end被调用)gs=孙子(孙子,12,男)print(姓名:,gs.name)print(年龄:,gs.age)print(性别:,gs.gender)执行结果如下:孙子的init开始被调用,Son1的init开始被调用,父母的init开始被调用,父母的init结束被调用,Son2的init开始被调用,父母的init结束被调用
(1)按顺序继承,哪个父类在最前面且它又有自己的构造函数,就继承它的构造函数;
class parent(object):def _ _ init _ _(self,name,* args,* * kwargs): #若要避免多重继承错误,请使用变长参数,接受参数print(parent的init开始被调用)self.name=name print(parent的init结束被调用)class son 1(parent):def _ _ init _ _(self,name,age,* args):#若要避免多重继承错误,请使用变长参数,并接受参数print(Son1的init开始被调用)_ _ init _ _ (name,* args,* * kwargs) #若要避免多重继承错误,请使用变长参数,接受参数print( son 1的init端被调用)class son 2(parent):def _ _ init _ _(self,name,gender,* args):#若要避免多重继承错误,请使用变长参数,接受参数print(Son2 init开始被调用)self.gender=gendersuper()。_ _ init _ _ (name,* args,* * kwargs) #为避免多重继承错误,使用变长参数,接受参数print( son 2的init端被调用)Class sun(son 1,son2): def __init__ (self,name,age,gender):print( sun的init开始被调用)#多重继承时,与使用类名相比,_ _ init _ _ method,要把每一个父类都重新写一遍#而super只用一句话来执行所有父类方法,这也是多重继承要求传递所有参数的一个原因# Super(孙子,Self)。_ _ init _ _(姓名,年龄,性别)与下面的super()作用相同。__init__(姓名,年龄,性别)print(孙子的init端称为)print(孙子。__mro__) #搜索顺序gs=孙子(孙子,12,男)print(姓名:,gs.name)print(年龄:,Gs.age)print(性别:,gs.gender) 结果如下:(class _ _ main _ _。孙子,类 _ _ main _ _。 son1 ,类 _ _ main _ _。son2 ,class _ _ main _ _ _ _ _ _ Class object )孙子的init开始被称为Son1的init开始被称为Son2的init开始被称为父母的init结束被称为Son2的init结束被称为孙子的init结束被称为姓名:孙子年龄:12性别:男 (2)如果最前面第一个父类没有构造函数,则继承第2个的构造函数,第2个没有的话,再往后找,以此类推。
3.多继承时使用super调用父类属性方法的注意事项
3.1不使用super调用父类方法,使用父类名.方法名的形式。注意:上面代码里当在子类中通过父类名调用时,parent被执行了2次3.2 使用super调用父类中的方法,注意分析程序的执行顺序。注意:在上面模块中,当在子类中通过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__,在单继承上用法基本无差
class Parent(object):def _ _ init _ _(self,Name): print(parent的init开始被调用)self.name=name print(parent的init结束被调用)class son 1(Parent):def _ _ init _ _(self,Name,Age): print(Son1的init开始被调用)self.age=agesuper()。_ _ init _ _ (name) #单一继承无法提供所有参数Print (SON1的init end被调用)类孙子(SON1): def _ _ init _ _ (self,name,age,gender): print(孙子的init开始被调用)super()。__init__(name,age) #单一继承无法提供所有参数print(孙子的init ends to be called) gs=孙子(孙子,12,男)print (name:,gs.name)print (age:,gs.age)统一声明:关于博客原创内容,部分内容可能参考自互联网,如有原创链接,将予以引用;如果找不到原文链接,如有侵权请联系删除。关于转载博客,如有原创链接,会做声明;如果找不到原文链接,如有侵权请联系删除。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。