python-study-22
复习
上节课复习 1、__init__方法:用于在调用类时/实例化时自动触发,为对象初始化自己独有的特征 class People: country='China' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def eat(self): self.name self.func() #实例化: #1、创造一个空对象p1 #2、触发对象下的__init__方法,让后将p1,'egon',18,'male'一同传入 p1=People('egon',18,'male') 2、绑定方法: 在类中定义的函数,类可以使用,但类去调用就是一个普通的函数而已,没有自动传值一说 但类中定义的函数,其实是给对象用的,而且是绑定给对象用的 绑定给谁就应该由谁来调用,谁来调用就会将谁当作第一个参数自动传入 p1.eat() 强调对象的精髓: 对象不仅包含一系列数据(自己独有的+与其他对象共有的),还包含专门操作该数据的方法 3、在python3中统一类与类型的概念 l=[1,2,3] #l=list([1,2,3]) l.append(4) l1=[4,5,6] l1.append(5) class Foo:pass 4、继承 继承是一种新建类的方式,新建的类称为子类或派生类,被继承成类的称为父类 或超类或基类, 继承的特性:子类可以“遗传”父类的属性 用继承的目的就是:减少代码冗余 class Foo: pass class Bar(Foo): pass 新式类:继承了object类的类Foo,以及Foo类的子类 经典类:没有继承object类的类Foo,以及Foo类的子类 只有在python2中才有经典类,在python3中全为新式类(不继承任何类的类默认就会继承object) class Foo(object): pass 5、派生 在子中定义的新属性称为派生,在使用中,始终以自己有的为准 class Foo: pass class Bar(Foo): x=1 def func(self): pass 6、在子类派生出的新方法中重用父类功能 指名道姓(跟继承无关):类名.函数(全部参数。。。) 今日内容: 1、组合(*****) 2、菱形继承问题(新式类vs经典类)(*****) 3、在子派生的新方法中重用父类功能的两种方式(*****) 4、多态与多态性(*****) 5、封装(*****)
组合--对象关联
''' 1、什么是组合 组合就是一个类的对象具备某一个属性,该属性的值是指向另外一个类的对象 2、为何用组合 组合也是用来解决类与类直接代码冗余问题的 3、如何用组合 class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,stu_id): OldboyPeople.__init__(self,name,age,sex) self.stu_id=stu_id def choose_course(self): print('%s is choosing course' %self.name) class OldboyTeacher(OldboyPeople): def __init__(self, name, age, sex, level): OldboyPeople.__init__(self,name,age,sex) self.level=level def score(self,stu,num): stu.score=num print('老师[%s]为学生[%s]打分[%s]' %(self.name,stu.name,num)) stu1=OldboyStudent('猪哥',19,'male',1) tea1=OldboyTeacher('egon',18,'male',10) stu1.choose_course() tea1.score(stu1,100) print(stu1.__dict__) ''' class Course: def __init__(self,name,period,price): self.name=name self.period=period self.price=price def tell_info(self): msg=""" 课程名:%s 课程周期:%s 课程价钱:%s """ %(self.name,self.period,self.price) print(msg) class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,stu_id): OldboyPeople.__init__(self,name,age,sex) self.stu_id=stu_id def choose_course(self): print('%s is choosing course' %self.name) class OldboyTeacher(OldboyPeople): def __init__(self, name, age, sex, level): OldboyPeople.__init__(self,name,age,sex) self.level=level def score(self,stu,num): stu.score=num print('老师[%s]为学生[%s]打分[%s]' %(self.name,stu.name,num)) # 创造课程 python=Course('python全栈开发','5mons',3000) linux=Course('linux运维','5mons',800) # python.tell_info() # linux.tell_info() # 创造学生与老师 stu1=OldboyStudent('猪哥',19,'male',1) tea1=OldboyTeacher('egon',18,'male',10) # 将学生、老师与课程对象关联/组合 stu1.course=python tea1.course=linux stu1.course.tell_info() tea1.course.tell_info()
菱形继承--属性查找
#coding:utf-8 ''' 1、菱形继承 当一个子继承多个父类时,多个父类最终继承了同一个类,称之为菱形继承 2、菱形继承的问题: python2区分经典类与新式类,如果子的继承是一个菱形继承,那么经典类与新式类的区别为? 经典类下查找属性:深度优先查找 新式类下查找属性:广度优先查找 ''' class G(object): # def test(self): # print('from G') pass class E(G): # def test(self): # print('from E') pass class B(E): # def test(self): # print('from B') pass class F(G): # def test(self): # print('from F') pass class C(F): # def test(self): # print('from C') pass class D(G): # def test(self): # print('from D') pass class A(B,C,D): def test(self): print('from A') # pass obj=A() print(A.mro()) # obj.test() #A->B->E-C-F-D->G-object
继承中两种重用方法的方式
# 在子派生的新方法中重用父类功能的两种方式 # 方式一:与继承无关 #指名道姓法,直接用:类名.函数名 # class OldboyPeople: # school = 'oldboy' # # def __init__(self, name, age, sex): # self.name = name # self.age = age # self.sex = sex # # class OldboyStudent(OldboyPeople): # def __init__(self,name,age,sex,stu_id): # OldboyPeople.__init__(self,name,age,sex) # self.stu_id=stu_id # # def choose_course(self): # print('%s is choosing course' %self.name) # 方式二:严格依赖继承属性查找关系 # super()会得到一个特殊的对象,该对象就是专门用来访问父类中的属性的(按照继承的关系) # super().__init__(不用为self传值) # 注意: # super的完整用法是super(自己的类名,self),在python2中需要写完整,而python3中可以简写为super() # class OldboyPeople: # school = 'oldboy' # # def __init__(self, name, age, sex): # self.name = name # self.age = age # self.sex = sex # # class OldboyStudent(OldboyPeople): # def __init__(self,name,age,sex,stu_id): # # OldboyPeople.__init__(self,name,age,sex) # super(OldboyStudent,self).__init__(name,age,sex) # self.stu_id=stu_id # # def choose_course(self): # print('%s is choosing course' %self.name) # # # stu1=OldboyStudent('猪哥',19,'male',1) # print(stu1.__dict__) # # print(OldboyStudent.mro()) class A: def f1(self): print('A.f1') class B: def f2(self): super().f1() print('B.f2') class C(B,A): pass obj=C() print(C.mro()) #C-》B->A->object obj.f2()
多态--子类 抽象 鸭子类型
''' 1 什么是多态 多态指的是同一种事物的多种形态 水-》冰、水蒸气、液态水 动物-》人、狗、猪 2 为和要用多态 多态性: 继承同一个类的多个子类中有相同的方法名 那么子类产生的对象就可以不用考虑具体的类型而直接调用功能 3 如何用 ''' import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def speak(self): pass @abc.abstractmethod def eat(self): pass # Animal() #强调:父类是用来指定标准的,不能被实例化 class People(Animal): def speak(self): print('say hello') def eat(self): pass class Dog(Animal): def speak(self): print('汪汪汪') def eat(self): pass class Pig(Animal): def speak(self): print('哼哼哼') def eat(self): pass peo1=People() dog1=Dog() pig1=Pig() # # # peo1.speak() # dog1.speak() # pig1.speak() # def my_speak(animal): # animal.speak() # # my_speak(peo1) # my_speak(dog1) # my_speak(pig1) # # l=[1,2,3] # s='helllo' # t=(1,2,3) # # print(l.__len__()) # print(s.__len__()) # print(t.__len__()) # # # def len(obj): # # return obj.__len__() # # print(len(l)) # l.__len__() # print(len(s)) #s.__len__() # print(len(t)) # python推崇的是鸭子类型,只要你叫的声音像鸭子,并且你走路的样子也像鸭子,那你就是鸭子 class Disk: def read(self): print('disk read') def write(self): print('disk wirte') class Process: def read(self): print('process read') def write(self): print('process wirte') class File: def read(self): print('file read') def write(self): print('file wirte') obj1=Disk() obj2=Process() obj3=File() obj1.read() obj1.write()
今日作业: 1、多重继承的执行顺序,请解答以下输出结果是什么?并解释。 class A(object): def __init__(self): print('A') super(A, self).__init__() class B(object): def __init__(self): print('B') super(B, self).__init__() class C(A): def __init__(self): print('C') super(C, self).__init__() class D(A): def __init__(self): print('D') super(D, self).__init__() class E(B, C): def __init__(self): print('E') super(E, self).__init__() class F(C, B, D): def __init__(self): print('F') super(F, self).__init__() class G(D, B): def __init__(self): print('G') super(G, self).__init__() if __name__ == '__main__': g = G() f = F() 2、什么是新式类,什么是经典类,二者有什么区别?什么是深度优先,什么是广度优先? 3、解释多态、多态性、鸭子类型 4、定义课程类、班级类、老师类、学生类,要求如下 1、一名老师可以带多个班级,一名学生可以属于多个班级 2、班级绑定课程 3、基于继承或组合减少代码冗余 选做:按照图,实现其他类及其关系
##1 # class A(object): # def __init__(self): # print('A') # super(A, self).__init__() # # # class B(object): # def __init__(self): # print('B') # super(B, self).__init__() # # # class C(A): # def __init__(self): # print('C') # super(C, self).__init__() # # # class D(A): # def __init__(self): # print('D') # super(D, self).__init__() # # # class E(B, C): # def __init__(self): # print('E') # super(E, self).__init__() # # # class F(C, B, D): # def __init__(self): # print('F') # super(F, self).__init__() # # # class G(D, B): # def __init__(self): # print('G') # super(G, self).__init__() # # # print(F.mro()) # print(G.mro()) # if __name__ == '__main__': # g = G() # GDAB # f = F() # FCBDA # [<class '__main__.F'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>] # [<class '__main__.G'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>] ##2 #向上能回溯到object就是新式类 否则是经典类 p3都是新式类 p2既有新式类又有经典类 #新式类用广度优先,经典类用深度优先 属性查找算法 ##3 # 多态指的是同一事物的多种形态 # 继承同一个父类的多个子类中有相同的方法名,那么子类产生的对象就可以不用考虑具体的类型而直接调用功能 #独立的类 方法名相同 ##4 class Classes: def __init__(self,name,semester='1',date='5.23',teacher='egon'): self.name=name self.semester=semester self.date=date self.teacher=teacher def tell_info(self): msg=""" 班级名:%s 学期:%s 开课日期:%s 班主任:%s """ %(self.name,self.semester,self.date,self.teacher) print(msg) class Course: def __init__(self,name,period,price): self.name=name self.period=period self.price=price def tell_info(self): msg=""" 课程名:%s 课程周期:%s 课程价钱:%s """ %(self.name,self.period,self.price) print(msg) class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,stu_id): OldboyPeople.__init__(self,name,age,sex) self.stu_id=stu_id self.cla = [] def choose_course(self): print('%s is choosing course' %self.name) class OldboyTeacher(OldboyPeople): def __init__(self, name, age, sex, level): OldboyPeople.__init__(self,name,age,sex) self.level=level self.cla=[] def score(self,stu,num): stu.score=num print('老师[%s]为学生[%s]打分[%s]' %(self.name,stu.name,num)) #创造班级 sh_py1 = Classes('sh_oldboy1') sh_lin1=Classes('sh_oldboy2') # 创造课程 python=Course('python全栈开发','5mons',3000) linux=Course('linux运维','5mons',800) #班级和课程绑定 sh_py1.course=python sh_lin1.course=linux #创造老师和学生 stu1=OldboyStudent('猪哥',19,'male',1) tea1=OldboyTeacher('egon',18,'male',10) #学生和老师与班级绑定 stu1.cla.append(sh_py1) stu1.cla.append(sh_lin1) tea1.cla.append(sh_lin1) for i in stu1.cla: i.tell_info() #查看班级信息 i.course.tell_info() #查看课程信息