python中类的应用(继承与派生)
程序员文章站
2022-05-10 22:49:44
继承与派生
什么是继承
继承是一种新建类的方式,新建的类称为子类,子类会遗传父类的属性,可以减少代码冗余,
在python中,子类(派生类)可以继承一个或者多个父类(基类...
继承与派生
什么是继承
继承是一种新建类的方式,新建的类称为子类,子类会遗传父类的属性,可以减少代码冗余, 在python中,子类(派生类)可以继承一个或者多个父类(基类,超类)
例如:
class Parent1: pass class Parent2(object): pass class Sub1(Parent1): pass class Sub2(Parent1,Parent2): pass print(Sub1.__bases__) #查看类的父类 print(Sub2.__bases__) print(Parent1.__bases__) #在python3新建的类,默认都有一个父类(object) #在python2中,默认是没有父类,可以添加(object)为父类 print(Parent2.__bases__)
python中类的分类
在python2中:
1、经典类,指的就是没有继承object类的类,以及该类的子类
2、新式类,指的就是继承object类的类,以及该类的子类
在python3中:
统一都是新式类
例如:
class OldboyPeople: school='oldboy' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def tell_info(self): print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex)) class OldboyStudent(OldboyPeople): def learn(self): print('%s is learning' %self.name) def tell_info(self): print('我是学生:',end='') class OldboyTreacher(OldboyPeople): def teach(self): print('%s is teaching' %self.name) def tell_info(self): print('我是老师:',end='') print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex)) stu1=OldboyStudent('lqx','19','male') teaching=OldboyTreacher('egon','23','female') print(stu1.__dict__) print(stu1.school) # print(stu1.x) #查找顺序,对象->子类->父类 没有就抛异常 print(teaching.__dict__) # 如果子类有这个函数,就不会去父类去找 stu1.tell_info() teaching.tell_info() #属性查找: class Foo: def f1(self): print('foo.f1') def f2(self): #self应该为Bar初始化的obj对象 print('foo.f2') self.f1() #Bar初始化的obj.f1() class Bar(Foo): def f1(self): print('bar.f1') obj=Bar() print(obj.__dict__) obj.f2() #先在bar类中查找,如果没有就会去父类查找, # >>>foo.f2 # bar.f1
子类重用父类的方法
指名道姓的使用
#子类指名道姓使用父类属性 #实现学生还有课程、学号 class OldboyPeople: school='oldboy' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def tell_info(self): print('<名字:%s 年龄:%s 性别:%s 课程:%s 学号:%s>' %(self.name,self.age,self.sex,self.coutse,self.stu_id)) class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,coutse,stu_id): OldboyPeople.__init__(self,name,age,sex) #子类指名道姓使用父类属性 self.coutse=coutse self.stu_id=stu_id def learn(self): print('%s is learning' %self.name) def tell_info(self): print('我是学生:',end='') OldboyPeople.tell_info(self) #子类指名道姓使用父类属性 stu1=OldboyStudent('lqx','19','male','python','123') stu1.tell_info()
使用super来调用父类的方法
1、之前使用指名道姓的引用另一个类,或者父类的方法。
2、现在使用super(本类名.self).方法 的方式调用父类的方法
3、这种方法只能调用父类的方法
class OldboyPeople: school = 'Oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def tell_info(self): print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex)) class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,course): # OldboyPeople.__init__(self,name,age,sex) super(OldboyStudent,self).__init__(name,age,sex) self.course=course def tell_info(self): print('我是学生: ',end='') # OldboyPeople.tell_info(self) super(OldboyStudent,self).tell_info() stu1=OldboyStudent('lqx','12','male','python') print(stu1.name,stu1.age,stu1.sex,stu1.course) stu1.tell_info()
super方法
class Foo: # def f2(self): # print('>>>>2') def f1(self): print('foo.f1') Foo.f2(123) class Bar: def f2(self): print('bar f2') class Sub(Bar,Foo): pass s=Sub() print(Sub.mro()) #[, , , ] s.f1() #说明严格按照mro()中的查找顺序来查找 #查找顺序,Sub->Bar->Foo
组合的使用
#学生有年龄名字,性别,学号,还有生日,使用组合添加出生日 #组合区别于继承,什么有什么的一种关系 class OldboyPeople: school='oldboy' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def tell_info(self): print('<名字:%s 年龄:%s 性别:%s 课程:%s 学号:%s>' %(self.name,self.age,self.sex,self.coutse,self.stu_id)) class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,coutse,stu_id,date_obj): OldboyPeople.__init__(self,name,age,sex) self.coutse=coutse self.stu_id=stu_id self.birth=date_obj #3、把date_obj添加到self这个对象中 def learn(self): print('%s is learning' %self.name) def tell_info(self): print('我是学生:',end='') OldboyPeople.tell_info(self) class OldboyTreacher(OldboyPeople): def __init__(self,name,age,sex,level,salary): OldboyPeople.__init__(self, name, age, sex) self.level = level self.salary = salary def teach(self): print('%s is teaching' %self.name) def tell_info(self): print('我是老师:',end='') print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex)) class Date: def __init__(self,year,mon,day): self.year = year self.mon = mon self.day = day def tell_birth(self): print('出生日期是:%s-%s-%s' % (self.year, self.mon, self.day)) date_obj=Date('1921',21,23) #1、先初始化生日得到一个对象 stu1=OldboyStudent('lqx','19','male','python','12',date_obj) #2、初始化学生类,把初始化生日的对象带入一起初始化 stu1.birth.tell_birth() #4、就可以调用对象stu1中birth的属性 teacher1=OldboyTreacher('www','123','female',10,12) date_obj2=Date(1990,2,18) teacher1.brith=date_obj2 # 添加一个生日,把生日任何人都有生日,把生日放到父类中,初始化的时候就会有生日 class OldboyPeople: school='oldboy' def __init__(self,name,age,sex,date_obj): self.name=name self.age=age self.sex=sex self.birth=date_obj def tell_info(self): print('<名字:%s 年龄:%s 性别:%s >' %(self.name,self.age,self.sex)) class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,coutse,stu_id,date_obj): OldboyPeople.__init__(self,name,age,sex,date_obj) self.coutse=coutse self.stu_id=stu_id def learn(self): print('%s is learning' %self.name) def tell_info(self): print('我是学生:',end='') OldboyPeople.tell_info(self) print('课程:%s 学号:%s' %(self.coutse,self.stu_id)) class OldboyTreacher(OldboyPeople): def __init__(self,name,age,sex,level,salary,date_obj): OldboyPeople.__init__(self, name, age, sex,date_obj) self.level = level self.salary = salary def teach(self): print('%s is teaching' %self.name) def tell_info(self): print('我是老师:',end='') print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex)) class Date: def __init__(self,year,mon,day): self.year = year self.mon = mon self.day = day def tell_birth(self): print('出生日期是:%s-%s-%s' % (self.year, self.mon, self.day)) class OldboySale(OldboyPeople): def __init__(self,name,age,sex,kpi,date_obj): OldboyPeople.__init__(self,name,age,sex,date_obj) self.kpi=kpi def tell_info(self): print('销售:%s',end='') OldboyPeople.tell_info(self) date_obj=Date('1921',21,23) stu1=OldboyStudent('lqx','19','male','python','12',date_obj) stu1.birth.tell_birth() date_obj2=Date(1990,2,18) teacher1=OldboyTreacher('www','123','female',10,12,date_obj2) teacher1.birth.tell_birth() print(teacher1.__dict__) date_obj1=Date(1800,12,32) sale1=OldboySale('mmp','12','female',7.1,date_obj1) print(sale1.__dict__) sale1.birth.tell_birth() #学生选课,添加选择的课程,在初始化的时候初始化一个属性为list class OldboyPeople: school='oldboy' def __init__(self,name,age,sex,date_obj): self.name=name self.age=age self.sex=sex self.birth=date_obj def tell_info(self): print('<名字:%s 年龄:%s 性别:%s >' %(self.name,self.age,self.sex),end='') class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,date_obj,stu_id): OldboyPeople.__init__(self,name,age,sex,date_obj) self.coutse=[] self.stu_id=stu_id def learn(self): print('%s is learning' %self.name) def tell_info(self): print('我是学生:',end='') OldboyPeople.tell_info(self) print('学号:%s' %self.stu_id) class OldboyTreacher(OldboyPeople): def __init__(self,name,age,sex,level,salary,date_obj): OldboyPeople.__init__(self, name, age, sex,date_obj) self.level = level self.salary = salary self.courses=[] def teach(self): print('%s is teaching' %self.name) def tell_info(self): print('我是老师:',end='') print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex)) class Date: def __init__(self,year,mon,day): self.year = year self.mon = mon self.day = day def tell_birth(self): print('出生日期是:%s-%s-%s' % (self.year, self.mon, self.day)) class OldboySale(OldboyPeople): def __init__(self,name,age,sex,kpi,date_obj): OldboyPeople.__init__(self,name,age,sex,date_obj) self.kpi=kpi def tell_info(self): print('销售:%s',end='') OldboyPeople.tell_info(self) class Course: def __init__(self,name,price,period): self.name=name self.price=price self.period=period def tell_info(self): print('课程详细信息:(%s,%s,%s)' %(self.name,self.price,self.period)) Python=Course('python自动化',4000,'3mon') Linux=Course('linux学习',2000,'3mon') # date_obj=Date(1990,12,32) # tearch1=OldboyTreacher('egon','19','male',100,3000,date_obj) # tearch1.courses.append(Python) # for course in tearch1.courses: # course.tell_info() date_obj=Date(1994,21,12) stu1=OldboyStudent('LQX',29,'male',date_obj,'1') stu1.coutse.append(Linux) stu1.coutse.append(Python) stu1.tell_info() for coutse in stu1.coutse: coutse.tell_info()
抽象类
主要使用abc模块,实现归一化,父类有的方法,子类必须有。
需要在父类的方法头部加上@abc.abstractclassmethod
例如:
class File(metaclass=abc.ABCMeta): @abc.abstractmethod def read(self): #必须要定义下面的方法,如果没有就不让实例化 pass @abc.abstractmethod def write(self): pass class Sata(File): def read(self): pass def write(self): pass def asb(self): print('adsf') Fil=Sata() Fil.asb() print(Sata.mro())
继承的实现原理
1、继承顺序:
经典类:当类是经典类时,多继承情况下,在要查找属性不存在时,会按照深度优先的方式查找下去
新式类:当类是新式类时,多继承情况下,在要查询属性不存在时,会按照广度优先的方式查找下去
2、使用属性来查看继承的顺序:
print(类名.mro())
class A(object): # def test(self): # print('from A') pass class B(A): # def test(self): # print('from B') pass class C(A): # def test(self): # print('from C') pass class D(B): # def test(self): # print('from D') pass class E(C): # def test(self): # print('from E') pass class F(D,E): # def test(self): # print('from F') pass f1=F() print(F.mro())