面向对象,绑定方法与异常处理

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 《数据结构与面向对象程序设计》第六周学习总结

Python 面向对象

python学习笔记-面向对象进阶&异常处理

python学习笔记-面向对象进阶&异常处理

Java面向对象编程之异常处理机制

Python学习-08-面向对象编程进阶和异常处理