回归python培训——类与对象、继承、多态和多态性、封装、绑定方法和非绑定方法、反射
一、复习:
1、面向过程:核心是过程,过程就是解决问题的步骤,即先干什么,再干什么,基于面向过程设计程序,就好比在设计一条流水线,就是一种机械思维方法。
优点:复杂的问题简单化
缺点:可扩展性差(牵一发动全身)
应用场景:linux内核,httpd,git
2、面向对象编程:核心是对象,要理解对象应该把自己当成上帝,在上帝眼里一切存在的事物都是对象,不存在也可以创建出来,对象是特征(变量)与技能(函数)的结合
优点:可扩展性强
缺点:无法向面向过程一样准确的知道什么阶段发生什么事,会什么结果
应用场景:与用户层交互多的,公司内部的软件,游戏,互联网软件
二、在python3中统一了类与类型的概念,他们是一样的。
1 >>> s=str('asdf') 2 >>> s="asdf" 3 >>> type(s) 4 <class 'str'>
工厂函数 定义一个类,可以实例化一个个对象来。(str,list,dict,set。。)
产生一个对象会产生三个属性:id(在内存中的位置),类型(type)和数值(value)
1 # x=1 #x=int(1) 2 # #id 3 # #type 4 # #value 5 # print(id(x)) #身份 6 # print(type(x)) #类型 7 # print(x) #值
9 # #is:身份运算(身份判断函数) 10 # x=1 11 # y=1 12 # print(x is y) #判断id是否相等 13 True
== 是判断的值
id相等,它的值想等
id不等,它的值可能相等
三、类与对象
对象是特征(变量)与技能(函数)的结合,类是一系列对象共有的特征与技能的结合体
在现实生活中:先有对象,再总结归纳出的类
在程序中:一定是先定义类,再实例化出对象
定义类的语法:
class 类名:
```注释```
代码在定义阶段就会执行
类体(可以是任意代码)
中国人:
现实存在的中国人(对象)————》中国人类(共同的特征:中国人,共同的技能:说汉语)
程序中:
1 class Chinese: 2 country = 'China' 3 def __init__(self,name,age): 4 # print('====>') 5 self.name=name #p1.name='egon' 6 self.age=age #p1.age=18 7 8 def talk(self): #函数名字通常是动词 9 print('say chinese',self)
#类的第一种用法:实例化
1 p1=Chinese('egon',18) #__init__(p1,'egon',18)
#类的第二种用法:属性引用(增删改查)
1 # print(Chinese.country) #类的数据属性 2 # print(Chinese.__init__) #类的函数属性 3 # Chinese.__init__(1,2,3) #1.name=2 4 5 # print(Chinese.__dict__) #查看类的属性字典,或者说名称空间 6 7 # print(Chinese.country) 8 # print(Chinese.__dict__['country'])
#对象
1 p1=Chinese('egon',18) #__init__(p1,'egon',18) 2 # 3 # print(p1.name) 4 # print(p1.age) 5 # 6 # 7 # print(p1.__dict__) 8 # print(p1.__dict__['name'])
#类型与类是统一的
1 # print(type(p1))
1 p1=Chinese('egon',18) #__init__(p1,'egon',18) 2 p2=Chinese('alex',1000) #__init__(p1,'egon',18) 3 # print(id(p1.country)) 4 # print(id(p2.country)) 5 # print(id(Chinese.country)) 6 # 7 # print(Chinese.talk) 8 # print(p1.talk) 9 # print(p2.talk) 10 11 # print(p1) 12 # p1.talk() 13 # print(p2) 14 # p2.talk() 15 Chinese.talk(p1)
#定义在类内部的变量,是所有对象共有的,id全一样
#定义在类内部的函数,是绑定到所有对象的,是给对象来用,obj.func() 会把obj本身当做第一个参数出入
#绑定方法:绑定到谁身上,就是给谁用的,谁来调用就会自动把自己当做第一个参数传入
print(p1.x) #先从p1.__dict__,找不到再找类Chinese.__dict__,找不到就会报错
练习:每实例化一次计数一次,最后统计实例化次数;定义一个学生类
1 # class Foo: 2 # count=0 #Cinese.count sekf,ciybt 3 # def __init__(self,name): 4 # # print(self.count) 5 # #count+=1 #全局的count 6 # # self.count=10 # 对象自己的count,但事先没有定义 7 # Foo.count+=1 8 # self.name=name 9 # 10 # 11 # obj1=Foo('egon1') #Foo.count+=1 Foo.count=1 12 # obj2=Foo('egon2') #Foo.count+=1 Foo.count=2 13 # 14 # print(Foo.count) 15 # print(obj1.count) 16 # print(obj2.count)
1 # class Student: 2 # tag=123123123123123 #后期增加,扩展性强 3 # def __init__(self,ID,name,age): 4 # self.id=ID 5 # self.name=name 6 # self.age=age 7 # def walk(self): 8 # print('%s is walking' %self.name) 9 # 10 # s1=Student(1,'egon',18) 11 # s2=Student(2,'alex',10000) 12 # 13 # print(s1.id) 14 # print(s1.name) 15 # print(s1.age) 16 # print(s1.tag) 17 # print(s2.tag) 18 # 19 # 20 # s1.walk() 21 # s2.walk()
对象之间的交互
1 class Garen: 2 camp='Demacia' 3 def __init__(self,nickname,life_value=200,aggressivity=100): 4 self.nickname=nickname 5 self.life_value=life_value 6 self.aggressivity=aggressivity 7 8 def attack(self,enemy): 9 enemy.life_value-=self.aggressivity 10 11 12 class Riven: 13 camp = 'Noxus' 14 15 def __init__(self, nickname, life_value=100, aggressivity=200): 16 self.nickname = nickname 17 self.life_value = life_value 18 self.aggressivity = aggressivity 19 20 def attack(self, enemy): 21 enemy.life_value -= self.aggressivity 22 23 24 25 g=Garen('欧德博爱') 26 r=Riven('矮里渴死') 27 print(r.life_value) 28 29 g.attack(r) #发送了一条消息,称为向g发送了attack指令 30 print(r.life_value)
四、继承
1、什么是继承:一种创建新的类的方式
1 class ParentClass1: 2 pass 3 class ParentClass2: 4 pass 5 6 class SubClass1(ParentClass1): 7 pass 8 class SubClass2(ParentClass1,ParentClass2): 9 pass 10 # 11 # print(SubClass1.__bases__) 12 # print(SubClass2.__bases__) #__bases__查看继承哪些类
2、
python2中类分为:新式类与经典类
# class Foo(object): #新式类
# pass
#
# class Bar: #经典类
# pass
python3中类全都是新式类
# class Foo: #新式类
# pass
#
# print(Foo.__bases__)
3、寻找继承关系
继承的好处一:减少冗余代码
在子类定义新的属性,覆盖掉父类的属性,称为派生
1 # class Animal: 2 # def __init__(self, name, age, sex): 3 # self.name = name 4 # self.age = age 5 # self.sex = sex 6 # 7 # def eat(self): 8 # print('eating') 9 # 10 # def talk(self): 11 # print('%s 正在叫' %self.name) 12 # 13 # 14 # class People(Animal): 15 # def __init__(self, name, age, sex,education): 16 # Animal.__init__(self,name,age,sex) 17 # self.education=education 18 # 19 # def talk(self): 20 # Animal.talk(self) 21 # print('%s say hello' %self.name) 22 # 23 # class Pig(Animal): 24 # pass 25 # 26 # class Dog(Animal): 27 # pass 28 # 29 # 30 # peo1=People('alex',18,'male','小学肄业') #People.__init__ 31 # 32 # pig1=Pig('wupeiqi',20,'female') 33 # 34 # dog1=Dog('yuanhao',30,'male') 35 # 36 # print(peo1.education) 37 # 38 # 39 # peo1.talk() 40 # pig1.talk() 41 # dog1.talk()
1 #下列代码的结果是 2 3 # class Parent: 4 # def foo(self): 5 # print('Parent.foo') 6 # self.bar() #s.bar() 7 # 8 # def bar(self): 9 # print('Parent.bar') 10 # 11 # 12 # class Sub(Parent): 13 # def bar(self): 14 # print('Sub.bar') 15 # 16 # s=Sub() 17 # s.foo() #s.foo
1 # class Sub: 2 # def __init__(self): 3 # self.bar=123 4 # def bar(self): 5 # print('Sub.bar') 6 # 7 # s=Sub() 8 # print(s.__dict__) 9 # 123() #s.__dict__['bar']
1 class Animal: 2 def __init__(self, name, age, sex): 3 self.name = name 4 self.age = age 5 self.sex = sex 6 7 def eat(self): 8 print('eating') 9 10 def talk(self): 11 print('%s 正在叫' %self.name) 12 13 14 class People(Animal): 15 def __init__(self, name, age, sex,education): 16 Animal.__init__(self,name,age,sex) 17 self.education=education 18 19 def talk(self): 20 Animal.talk(self) 21 print('%s say hello' %self.name) 22 23 class Pig(Animal): 24 pass 25 26 class Dog(Animal): 27 pass 28 29 30 peo1=People('alex',18,'male','小学肄业') #People.__init__ 31 pig1=Pig('wupeiqi',20,'female') 32 dog1=Dog('yuanhao',30,'male') 33 34 35 # print(isinstance(peo1,People)) 36 # print(isinstance(pig1,Pig)) 37 # print(isinstance(dog1,Dog)) 38 39 40 # print(isinstance(peo1,Animal)) 41 # print(isinstance(pig1,Animal)) 42 # print(isinstance(dog1,Animal))
继承反映的是一种什么是什么的关系
组合也可以解决代码冗余问题,但是组合反映是一种什么有什么的关系
1 class Date: 2 def __init__(self,year,mon,day): 3 self.year=year 4 self.mon=mon 5 self.day=day 6 7 def tell(self): 8 print('%s-%s-%s' %(self.year,self.mon,self.day)) 9 10 class Teacher(People): 11 def __init__(self,name,age,sex,salary,year,mon,day): 12 self.name=name 13 self.age=age 14 self.sex=sex 15 self.salary=salary 16 self.birth=Date(year,mon,day) 17 18 class Student(People): 19 def __init__(self,name,age,sex,year,mon,day): 20 self.name=name 21 self.age=age 22 self.sex=sex 23 self.birth=Date(year,mon,day) 24 25 # t=Teacher('egon',18,'male',3000,1995,12,31) 26 # t.birth.tell()
1 # class File:#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。 2 # def read(self): #定接口函数read 3 # raise TypeError('类型错误') 4 # 5 # def write(self): #定义接口函数write 6 # raise TypeError('类型错误') 7 # 8 # 9 # class Txt(File): #文本,具体实现read和write 10 # def read(self): 11 # print('文本数据的读取方法') 12 # 13 # def write(self): 14 # print('文本数据的读取方法') 15 # 16 # class Sata(File): #磁盘,具体实现read和write 17 # def read(self): 18 # print('硬盘数据的读取方法') 19 # 20 # def write(self): 21 # print('硬盘数据的读取方法') 22 # 23 # class Process(File): 24 # # def read(self): 25 # # print('进程数据的读取方法') 26 # # 27 # # def write(self): 28 # # print('进程数据的读取方法') 29 # def xie(self): 30 # pass 31 # 32 # def du(self): 33 # pass 34 # p=Process() 35 # p.read() 36 37 38 # t=Txt() 39 # p=Process() 40 # d=Sata() 41 # 42 # print(isinstance(t,File)) 43 # print(isinstance(p,File)) 44 # print(isinstance(d,File)) 45 # 46 # 47 # 48 # t.read() 49 # p.read() 50 # d.read()
1 #抽象类 2 # import abc#导入abc模块,在需要强行实现的功能前加装饰器@abc.abstractmethod——子类必须实现的方法前加这个。 3 # class File(metaclass=abc.ABCMeta):#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。 4 # @abc.abstractmethod 5 # def read(self): #定接口函数read 6 # pass 7 # 8 # @abc.abstractmethod 9 # def write(self): #定义接口函数write 10 # pass 11 # 12 # class Process(File): 13 # def read(self): 14 # # print('进程数据的读取方法') 15 # pass 16 # def write(self): 17 # print('进程数据的读取方法') 18 # 19 # # def xie(self): 20 # # pass 21 # # 22 # # def du(self): 23 # # pass 24 # p=Process() 25 # p.read()
1 #继承的实现原理 2 # 3 # class E: 4 # # def test(self): 5 # # print('from E') 6 # pass 7 # 8 # class A(E): 9 # # def test(self): 10 # # print('from A') 11 # pass 12 # class D: 13 # # def test(self): 14 # # print('from D') 15 # pass 16 # class B(D): 17 # # def test(self): 18 # # print('from B') 19 # pass 20 # class C: 21 # # def test(self): 22 # # print('from C') 23 # pass 24 # 25 # class F(A,B,C): 26 # # def test(self): 27 # # print('from F') 28 # pass 29 # f=F() 30 # f.test()
1 class A: 2 # def test(self): 3 # print('from A') 4 # 5 # 6 # class B(A): 7 # # def test(self): 8 # # print('from B') 9 # pass 10 # class C(A): 11 # # def test(self): 12 # # print('from C') 13 # pass 14 # 15 # class D(B): 16 # # def test(self): 17 # # print('from D') 18 # pass 19 # 20 # class E(C): 21 # # def test(self): 22 # # print('from E') 23 # pass 24 # class F(D,E): 25 # # def test(self): 26 # # print('from F') 27 # pass 28 # f=F() 29 # f.test()
经典类:深度优先,F->D->B->A->E->C->H
新式类:广度优先,F->D->B->E->C->H->A
1 # class A: 2 # # def test(self): 3 # # print('from A') 4 # pass 5 # class B(A): 6 # # def test(self): 7 # # print('from B') 8 # pass 9 # class C(A): 10 # # def test(self): 11 # # print('from C') 12 # pass 13 # 14 # class D(B): 15 # # def test(self): 16 # # print('from D') 17 # pass 18 # 19 # class E(C): 20 # # def test(self): 21 # # print('from E') 22 # pass 23 # 24 # class H(A): 25 # def test(self): 26 # print('from H') 27 # pass 28 # class F(D,E,H): 29 # # def test(self): 30 # # print('from F') 31 # pass 32 # f=F() 33 # f.test() 34 # print(F.mro())
新式类:广度优先,F->D->B->E->C->H->A
1 # class Foo1: 2 # def test(self): 3 # print('from foo.test') 4 # 5 # 6 # class Bar(Foo1): 7 # def test(self): 8 # # Foo.test(self) 9 # # super().test() 10 # super(Bar,self).test() 11 # print('bar') 12 13 # b=Bar() 14 # b.test()
1 class Foo1: 2 # def test(self): 3 # print('from foo1.test') 4 pass 5 class Foo2: 6 def test(self): 7 print('from foo2.test') 8 9 10 class Bar(Foo1,Foo2): 11 def test(self): 12 # Foo1.test(self) 13 # Foo2.test(self) 14 super().test() 15 print('bar') 16 print(Bar.mro()) 17 b=Bar() 18 b.test()
多态是同一种事物的多种形态
1 class Animal: 2 def talk(self): 3 print('正在叫') 4 5 6 class People(Animal): 7 def talk(self): 8 print('say hello') 9 10 class Pig(Animal): 11 def talk(self): 12 print('哼哼哼') 13 14 class Dog(Animal): 15 def talk(self): 16 print('汪汪汪') 17 18 19 class Cat(Animal): 20 def talk(self): 21 print('喵喵喵') 22 23 peo1=People() 24 pig1=Pig() 25 dog1=Dog() 26 cat1=Cat()#后期添加 27 28 29 #多态性 30 31 # peo1.talk() 32 # dog1.talk() 33 # pig1.talk() 34 35 36 def func(x): 37 x.talk() 38 39 40 func(peo1) 41 func(pig1) 42 func(dog1) 43 func(cat1) 后期添加
封装
1 # class Foo: 2 # x=1 3 # def test(self): 4 # print('from test') 5 # 6 # print(Foo.x)
隐藏方式
1 # class Foo: 2 # __x=1 #_Foo__x 3 # def __test(self): #_Foo__test 4 # print('from test') 5 # print(Foo.__dict__) 6 # print(Foo.__x) 7 # Foo.test(123) 8 # print(Foo._Foo__x)
1 # class People: 2 # __country='China' 3 # def __init__(self,name,age,sex): 4 # self.__name=name #self._People__name=name #变成私有的 5 # self.__age=age #变成私有的 6 # self.__sex=sex #变成私有的 7 # 8 # def tell_info(self): #私有调用借口 9 # print('人的名字是:%s ,人的性别是:%s,人的年龄是:%s' %( 10 # self.__name, #p._People__name #私有的调用方式 11 # self.__age, 12 # self.__sex)) 13 # 14 # p=People('alex',18,'male') 15 # print(p.__dict__) 16 # p.tell_info() 17 # 18 # print(p.__name) 19 20 # p.__salary=3000 21 # print(p.__dict__) 22 # 23 # print(People.__dict__) 24 # 25 # People.__n=11111111111111111111111111 26 # print(People.__dict__) 27 # print(People.__n)
1 # class Parent: 2 # def foo(self): 3 # print('from parent.foo') 4 # self.__bar() #self._Parent__bar() 5 # 6 # def __bar(self): #_Parent__bar 7 # print('from parent.bar') 8 # 9 # 10 # class Sub(Parent): 11 # # def __bar(self): #_Sub__bar 12 # # print('from SUb.bar') 13 # pass 14 # s=Sub() 15 # s.foo() 16 17 # s._Parent__bar()
1 # class People: 2 # def __init__(self,name,age): 3 # self.__name=name 4 # self.__age=age 5 # 6 # def tell_info(self): 7 # print('人的名字是:%s ,人的年龄是:%s' %( 8 # self.__name, #p._People__name 9 # self.__age)) 10 # 11 # def set_info(self,x,y): 12 # if not isinstance(x,str): #通过isinstance函数判断输入为指定类型 13 # raise TypeError('名字必须是字符串类型') #主动抛出异常 14 # if not isinstance(y,int): 15 # raise TypeError('年龄必须是整数类型') 16 # 17 # self.__name=x 18 # self.__age=y 19 # 20 # 21 # p=People('alex',1000) 22 # p.tell_info() 23 # 24 # p.set_info('alex_SB',123) 25 # p.tell_info()
property是一个类
1 # property 2 3 # class Foo: 4 # @property #装饰器 不用加括号直接调用函数 5 # def test(self): 6 # print('from fooo') 7 # # test=property(test) 8 # 9 # f=Foo() 10 # # f.test() 11 # f.test 12 13 14 #测试人的bmi肥胖指数 15 # class People: 16 # def __init__(self,name,weight,height): 17 # self.name=name 18 # self.weight=weight 19 # self.height=height 20 # 21 # @property 22 # def bmi(self): 23 # return self.weight / (self.height ** 2) 24 # 25 # p=People('egon',75,1.80) 26 # p.height=1.82 27 # # print(p.bmi()) 28 # print(p.bmi)
1 # class People: 2 # def __init__(self,name,permmission=False): 3 # self.__name=name 4 # self.permmission=permmission 5 # @property 6 # def name(self): 7 # return self.__name 8 # 9 # @name.setter #已经有装饰器property后,直接使用setter,给name赋值 10 # def name(self,value): 11 # if not isinstance(value,str): 12 # raise TypeError('名字必须是字符串类型') 13 # self.__name=value 14 # 15 # @name.deleter #删除的需求 16 # def name(self): 17 # if not self.permmission: #如果删除为假,则不允许删除 18 # raise PermissionError('不允许的操作') 19 # del self.__name 20 # 21 # p=People('egon') 22 # 23 # # print(p.name) 24 # # 25 # # p.name='egon666' 26 # # print(p.name) 27 # # 28 # # p.name=35357 29 # p.permmission=True #开启删除的权限 30 # del p.name