类和对象
python3统一了类与类型的概念;类==类型;从一组对象中提取相似的部分就是类;特征与技能的结合体就叫做对象;
类的功能:
初始实例化;
属性引用;
1、数据属性;
2、函数属性;
对于一个实例来说,只一种功能:属性引用;
示例: class Garen: camp = 'Demacia' def __init__(self,nickname,aggresivity,life_value): self.nickname = nickname #gl.nickname=nickname self.aggrv=aggresivity self.life_value=life_value def attack(self,enemy): #定义技能,就是一个函数; print('is attacking',self,enemy) gl=Garen('草丛伦',82,100) #Garen.__init__(gl,'草丛伦',82,100) print(Garen.camp) #调用属性; print(Garen.__init__) #返回函数 print(Garen.attack) #返回函数 #对于一个实例来说,只一种功能:属性引用;对于实例本身来说只拥有数据属性; print(gl.nickname) print(gl.aggrv) print(gl.life_value) print(gl.camp) print(gl.attack) #返回绑定方法; print(Garen.attack) #通过类来调用自己的函数属性; 返回函数 Garen.attack(1,2) gl.attack('a') #Garen.attack(gl.'a')
类就是函数与数据的结合体;
对象的交互: class Garen: camp = 'Demacia' def __init__(self,nickname,aggresivity,life_value): self.nickname = nickname #gl.nickname=nickname self.aggrv=aggresivity self.life_value=life_value def attack(self,enemy): #定义技能,就是一个函数; print('is attacking',self,enemy) class Riven: camp="Noxus" def __init__(self,nickname,aggresivity,life_value): self.nickname = nickname #gl.nickname=nickname self.aggrv=aggresivity self.life_value=life_value def attack(self,enemy): #定义技能,就是一个函数; print('is attacking',self,enemy) enemy.life_value=self.aggrv # g1.life_value-=r1.aggrv g1 = Garen('草丛伦',82,100) r1 = Riven('锐',50,200) r1.attack(g1)
类:
class Chinese: dang='gongchandang' #共同特点 def __init__(self,name,age,gender): #私有特点 self.name=name self.age=age self.gender=gender def talk(self): #共有的功能 print('=====>') p1 = Chinese('egon',18,'female') #创建实例;现实中先有具体的实例,再定义类; p1. #p1.表示在调用实例自己;在调用p1的属性; print(p1.x) #先在p1自己里面找;def__init__,如果没有则再找类,类没有就报错; 例:print(p1.dang)
继承:
单继承
多继承
查看继承:
SubClass1.__bases__
示例: class A: pass class B(A): pass print(B.__bases__) print(A.__bases__) #默认继承object; (<class '__main__.A'>,) (<class 'object'>,) A没有object就叫做新式类;pytho3中所有类都叫做新式类;python2中叫经典类; 示例: class Animal: start='earth' def __init__(self,name,age,gender): self.name=name self.age=age self.gender=gender def run(self): print('running') def talk(self): print('talking') class People(Animal): def piao(self): #设计独特的技能 preint('is piaoing') class Pig(Animal): pass p1=People('alex',1000,'female') #pig1=Pig() print(p1.start) print(p1.running) print(p1.name)
继承与重用性;
继承用来解决代码的重用性;父类不能调用子类的功能;
继承顺序
深度优先
从左到右 python2
广度优先
python3
python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如
>>> F.mro() #等同于F.__mro__
[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类
示例: class Hero: def __init__(self,nickname,aggresivity,life_value): self.nickname = nickname #gl.nickname=nickname self.aggrv=aggresivity self.life_value=life_value def attack(self,enemy): #定义技能,就是一个函数; print('is attacking',self,enemy) enemy.life_value=self.aggrv # g1.life_value-=r1.aggrv class Garen(Hero): camp = 'Demacia' def fly(self): print('is flying') def attack(self): print('attacking') class Riven(Hero): camp="Noxus" g1 = Garen('草丛伦',30,10) g1.fly() r1=Riven('xxx',230,30) r1.attack()
组合与重用性;
组合:
一个对象的数据属性是另外一个对象;
继承表达‘是’的关系,组合表达‘有’的关系;
示例: class Teacher: def __init__(self.name): self.name=name self.birth=Date(1999,1,25) #实例属性来自于另外一个类; self.course=Course('python',11000,'4months') class Course: def __init__(self,name,price,period): self.name=name self.price=price self.period=period class Date: def __init__(self,year,month,day): self.year=year self.month=month self.day=day t1 = Teacher('egon') print(t.birth.year)
接口与归一化设计:
接口:
就是一堆函数的结合体;只定义一堆技能;
归一化示例:
class ALLFile: #接口类 接口功能只定义名称,而不去实现功能,具体实现在子类中; def read(self): #接口函数 pass def write(self): pass class Text(ALLFile): def read(self): print('text read') def write(self): print('text write') class Sata(ALLFile): def read(self): print('sata read') def write(self): print('sata write') t=Text() s=Sata() t.read() t.write() s.read() s.write() 抽象类: import abc #来实现抽象类; class ALLFile(metaclass=abc.ABCMeta): #抽象类 只是用来被别人继承,不能被调用; def test(self): print('testing') @abc.abstractmethod def read(self): #接口函数 pass @abc.abstractmethod #表示让子类必须实现;子类不指明会报错; def write(self): pass class Text(ALLFile): def read(self): print('text read') def write(self): print('text write') t=Text()
多态与多态性:
多态:
是一类事物的多种状态;同一种事物的不同形态,如序列类型包含字符串,列表,元组;
多态性:
优点:
程序的灵活性;
程序的扩展性;
示例: def func(obj): print(obj.__len__()) func(s) func(l) func(t) 示例: class Animal: def talk(self): print('talking') class Dog(Animal): def talk(self): #设计独特的技能 preint('say wqangwang') class Pig(Animal): print('say aoao') class Cat(Animal): def talk(self): print('cat talking') p1 = People() pig1=Pig() D1=Dog() c=Cat() 以上为多态,程序的实现者 def func(obj): obj.talk() func(p1) func(pig1) func(D1) func(c) 以上为多态性;程序的使用者,不能改变代码;
封装:
数据的封装;
保护隐私;
方法的封装;
主要隔离复杂度;
封装两个层面;
示例: class Foo: x=1 def __init__(self,name,money): self.name=name self.__money=money #相当于_Foo__money def get_money(self): print(self.__money) self.__spam() def __spam(self): #_Foo__spam 变形在定义时只会执行一次;后来赋值不会变形; print('from spam') f=Foo('alex',20000) f.get_money print(f.__dict__) print(Foo.__dict__) 对于第一层面的封装(隐藏),类名.和实例名.就是访问隐藏属性的接口(或者叫入口) 对于第二层面的封装(隐藏), 示例: class A: def spam(self): print("A.spam") def test(self): print('A.test') self.spam() class B(A): pass b1=B() b1.test() 二、 class A: def __spam(self): #_A__spam print("A.spam") def test(self): print('A.test') self.__spam() #self._A_spam class B(A): def __spam(self): #_B_spam print('B.spam') b1=B() b1.test() 特性: 用来提供接口的一种方式; 示例: class A: def __init__(self.name): self.__name=name @property #相当于C++中get def name(self): return self.__name @name.setter #相当于C++中set def name(self,value): if not isinstance(value,str): raise TypeError('%s must be str'%value) print('++++++?') self.__name=value @name.deleter def name(self): print('======>') raise AttributeError('can not delete') a=A('egon') print(a.name) a.name=2 print(a.name) del a.name
子类调用父类的方法:
当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表)
示例: class People: def __init__(self,name,age,gender): self.name=name self.age=age self.gender=gender def test(self): print('from A.test') class Teacher(People): def __init__(self,name,age,gender,level): People.__init__(self,name,age,gender) self.level=level t=Teacher('egon',18,'female','teach') print(t.level) 二、super() class People: def __init__(self,name,age,gender): self.name=name self.age=age self.gender=gender def test(self): print('from A.test') class Teacher(People): def __init__(self,name,age,gender,level): #People.__init__(self,name,age,gender) super.__init__(name,age,gender) self.level=level t=Teacher('egon',18,'female','teach') print(t.level)
具体的编程方法先出现;
面向对象的软件开发:
1、面向对象分析;
2、面向对象设计;
3、面向对象编程;
4、面向对象测试;
5、面向对象维护;
示例: class Foo: def __init__(self,name): self.name=name def __call__(self,*args,**kwargs): print('========>') f=Foo('egon') f() 反射: 示例: class Foo: def __init__(self,name): self.nae=name def func(self): print('func') print(hasattr(Foo,'func')) f=Foo('egon') print(hasattr(f,'x')) f.x=1 print(getattr(f,'x')) print(getattr(Foo,'func')) if hasattr(f,'func') aa=getattr(f,'func') aa() print(getattr(f,'y',None)) #f.y=1 #f y 1 setattr(f,'y') #设定值; print(f.__dict__) delattr(f,'y') print(f.__dict__)
socker
用于C/S架构;
用户态
内核态
套接字发展史及分类;
基于文件类型的套接字家族
示例: 服务端: import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.bind(('127.0.0.1',8080)) #插入卡 phone.listen(5) #开机 conn, addr=phone.accept() #接电话 建立连接,客户端地址; print('tcp的连接',conn) print('客户端的地址',addr) data = conn.recv(1024) #接收1024个字节; 收消息 print('from client msg :%s' %data) conn.send(data.upper()) #发消息; conn.close() #挂电话 phone.close() #关手机 客户端: import socket client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8080)) #拨通电话; client.send('hello'.encode('utf-8')) data=client.recv(1024) print(data) client.close()