面向对象,绑定方法与异常处理
Posted 冷风中行走~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象,绑定方法与异常处理相关的知识,希望对你有一定的参考价值。
1.1 继承与派生
1.1.1 什么是继承
是一种新建类的方式,新建的类称为子类,子类会遗传父类的属性,可以减少代码冗余
在python中,子类(派生类)可以继承一个或者多个父类(基类,超类)
python中类的继承分为:单继承和多继承
class Parent1: #定义父类 pass class Parent2(object): #定义父类 pass class Sub1(Parent1): ##单继承,基类是Parent1,派生类是Sub1 pass class Sub2(Parent1,Parent2): #python支持多继承,用逗号分隔开多个继承的类 pass
查看继承
print(Sub1.__bases__) #__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类 print(Sub2.__bases__) 提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。 print(Parent1.__bases__) print(Parent2.__bases__)
在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=\'\') print(\'<名字:%s 年龄:%s 性别:%s>\' % (self.name, self.age, self.sex)) class OldboyTeacher(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(\'牛榴弹\',18,\'male\') teacher1=OldboyTeacher(\'egon\',18,\'male\') print(stu1.__dict__) print(stu1.school) print(stu1.x) stu1.tell_info() teacher1.tell_info()
属性查找
继承描述的是子类与父类之间的关系,是一种什么是什么的关系。要找出这种关系,必须先抽象再继承
抽象即抽取类似或者说比较像的部分。
class Foo: def f1(self): print(\'Foo.f1\') def f2(self): #self=obj print(\'Foo.f2\') self.f1() #obj.f1() class Bar(Foo): def f1(self): print(\'Bar.f1\') obj=Bar() print(obj.__dict__) obj.f2()
1.2 子类重用父类方法part1:
在开发程序的过程中,如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同时
我们不可能从头开始写一个类B,这就用到了类的继承的概念。
通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用
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=\'\') # self.tell_info() #stu1.tell_info() OldboyPeople.tell_info(self) stu1=OldboyStudent(\'牛榴弹\',18,\'male\') stu1.tell_info()
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,stu_id): # self.name=name # self.age=age # self.sex=sex OldboyPeople.__init__(self,name,age,sex) self.course=course self.stu_id=stu_id def learn(self): print(\'%s is learning\' %self.name) def tell_info(self): print(\'我是学生:\',end=\'\') # self.tell_info() #stu1.tell_info() OldboyPeople.tell_info(self) stu1=OldboyStudent(\'牛榴弹\',18,\'male\',\'Python\',1) stu1.tell_info()
1.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,stu_id,year,mon,day): OldboyPeople.__init__(self,name,age,sex) self.course=course self.stu_id=stu_id self.year=year self.mon=mon self.day=day def learn(self): print(\'%s is learning\' %self.name) def tell_info(self): print(\'我是学生:\',end=\'\') # self.tell_info() #stu1.tell_info() OldboyPeople.tell_info(self) def tell_birth(self): print(\'出生日期是:<%s-%s-%s>\' %(self.year,self.mon,self.day)) class OldboyTeacher(OldboyPeople): def __init__(self, name, age, sex, level,salary,year,mon,day): OldboyPeople.__init__(self, name, age, sex) self.level=level self.salary=salary self.year=year self.mon=mon self.day=day def tell_birth(self): print(\'出生日期是:<%s-%s-%s>\' %(self.year,self.mon,self.day)) def teach(self): print(\'%s is teaching\' % self.name) def tell_info(self): print(\'我是老师:\', end=\'\') OldboyPeople.tell_info(self) stu1=OldboyStudent(\'牛榴弹\',18,\'male\',\'Python\',1,1983,3,11) teacher1=OldboyTeacher(\'啊狗\',18,\'female\',10,4000,1990,2,17) stu1.tell_birth() teacher1.tell_birth()
组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同,
1.继承的方式
通过继承建立了派生类与基类之间的关系,它是一种\'是\'的关系,比如白马是马,人是动物。
当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生是人
2.组合的方式
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...
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, stu_id,): OldboyPeople.__init__(self, name, age, sex) self.course = course self.stu_id = stu_id def learn(self): print(\'%s is learning\' % self.name) def tell_info(self): print(\'我是学生:\', end=\'\') # self.tell_info() #stu1.tell_info() OldboyPeople.tell_info(self) class OldboyTeacher(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=\'\') OldboyPeople.tell_info(self) 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)) stu1 = OldboyStudent(\'牛榴弹\', 18, \'male\', \'Python\', 1,) date_obj1=Date(1983, 3, 11) stu1.birth=date_obj1 teacher1 = OldboyTeacher(\'啊狗\', 18, \'female\', 10, 4000) date_obj2=Date( 1990, 2, 17) teacher1.birth=date_obj2 # print(stu1.birth) # print(teacher1.birth) stu1.birth.tell_birth() #date_obj1.tell_birth() teacher1.birth.tell_birth()
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, course, stu_id,date_obj): OldboyPeople.__init__(self, name, age, sex,date_obj) self.course = course self.stu_id = stu_id def learn(self): print(\'%s is learning\' % self.name) def tell_info(self): print(\'我是学生:\', end=\'\') # self.tell_info() #stu1.tell_info() OldboyPeople.tell_info(self) class OldboyTeacher(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=\'\') OldboyPeople.tell_info(self) 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(\'我是销售: \',end=\'\') OldboyPeople.tell_info(self) 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_obj1=Date(1983, 3, 11) sale1=OldboySale(\'歪歪\',38,\'male\',7.3,date_obj1) # sale1.birth=date_obj1 # sale1.tell_info() sale1.birth.tell_birth()
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, stu_id,date_obj): OldboyPeople.__init__(self, name, age, sex,date_obj) self.courses=[] self.stu_id = stu_id def learn(self): print(\'%s is learning\' % self.name) def tell_info(self): print(\'我是学生:\', end=\'\') # self.tell_info() #stu1.tell_info() OldboyPeople.tell_info(self) class OldboyTeacher(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=\'\') OldboyPeople.tell_info(self) 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(\'我是销售: \',end=\'\') OldboyPeople.tell_info(self) 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 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自动化养猪\',3000,\'3mon\') Linux=Course(\'大数据分析-linux\',3000,\'3mon\') date_obj=Date(1993,3,13) teacher1=OldboyTeacher(\'egon\',18,\'male\',100,3000,date_obj) teacher1.courses.append(Python) teacher1.courses.append(Linux) # print(teacher1.courses) for course in teacher1.courses: course.tell_info() stu1=OldboyStudent(\'xxxx\',28,\'female\',1,date_obj) # print(stu1.courses) stu1.courses.append(Python) stu1.courses.append(Linux) print(stu1.courses)
1.4 抽象类
1.4.1 什么是抽象类
与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化
为什么要有抽象类
如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。
比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。。。。。。你永远无法吃到一个叫做水果的东西。
从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。
从实现角度来看,抽象类与普通类的不同之处在于:抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的,即将揭晓答案
import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def eat(self): pass @abc.abstractmethod def run(self): pass class People(Animal): def eat(self): pass def run(self): pass class Pig(Animal): def eat(self): pass def run(self): pass peo1=People() pig1=Pig()
1.4.2 抽象类与接口
抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。
抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计
import abc class File(metaclass=abc.ABCMeta): @abc.abstractmethod def read(self): pass @abc.abstractmethod def write(self): pass class Disk(File): def read(self): print(\'disk read\') def write(self): print(\'disk write\') class Process(File): def read(self): print(\'Process read\') def write(self): print(\'Process write\') d=Disk() p=Process() d.read() d.write() p.read() p.write()
1.5 继承的实现原理
继承顺序
在Java和C#中子类只能继承一个父类,而Python中子类可以同时继承多个父类,如A(B,C,D)
如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性
如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先
图1-1
图1-2
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()) # f1.test()
1.6 子类重用父类的方法part2
1.6.1 方法一:指名道姓,即父类名.父类方法()
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(\'egon\',18,\'male\',\'python\') # print(stu1.name,stu1.age,stu1.sex,stu1.course) stu1.tell_info()
1.6.2 方法二:super()
class Foo: def f2(self): print(\'====?>\') def f1(self): print(\'Foo.f1\') # super().f2() Foo.f2(123) class Bar: def f2(self): print(\'Bar f2\') class Sub(Foo,Bar): pass s=Sub() # print(Sub.mro()) # [<class \'__main__.Sub\'>, # <class \'__main__.Foo\'>, # <class \'__main__.Bar\'>, # <class \'object\'>] s.f1()
强调:二者使用哪一种都可以,但最好不要混合使用
即使没有直接继承关系,super仍然会按照mro继续往后查找
1.6.3 指名道姓与super()的区别
当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表)
1.7 多态与多态性
1.7.1 多态:同一种事物的多种形态
import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod 20182318 2019-2020-1 《数据结构与面向对象程序设计》第六周学习总结