一、面向对象的程序设计
面向过程:核心是过程二字,过程指的是问题的解决步骤,即先干什么再干什么,基于面向过程去设计程序就好比在设计一条流水线,是一种机械式的思维方式
优点:复杂的问题流程化,进而简单化
缺点:可扩展性差
应用:脚本程序,比如linux系统管理脚本,著名案例:linux内核,httpd,git
面向对象:核心是对象二字,对象就是特征与技能的结合体,如果把设计程序比喻成
创造一个世界,那你就是这个世界的上帝,与面向过程对机械流水的模拟形式鲜明的对比面向对象更加注重的对现实世界的模拟。
优点:可扩展性
缺点:
应用:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方
面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。
二、类与对象
类即种类,类别,对象是特征和与技能的结合体,那么类就是一系列对象相似的特征与技能的结合体
在现实世界中:先有一个个具体存在的对象----》(总结相似之处)---》现实中的类
在程序中:一定是先定义类,后调用类来产生对象
类
1.类具有数据属性和方法属性
2.类在定义阶段会执行;也会产生名称空间
3.操作类的属性,等同于从类的名称空间字典中获取值
4.用类直接操作其函数属性,需要传参数到函数
1 class OldboyStudent: 2 school = 'oldboy' #类的数据属性 3 def learn(self): #类的函数属性 4 print('is learning') 5 6 def eat(self): 7 print('is eating') 8 print('======>') 9 10 #类体的代码在类定义阶段就会执行,理所应当会产生类的名称空间,用__dict__属性查看 11 # print(OldboyStudent.__dict__) 12 13 #类的属性操作 14 print(OldboyStudent.__dict__['school']) 15 print(OldboyStudent.__dict__['learn']) 16 17 print(OldboyStudent.school) #等同于OldboyStudent.__dict__['school'] 18 print(OldboyStudent.learn) #等同于OldboyStudent.__dict__['learn'] 19 '''======> 20 {'__module__': '__main__', 'school': 'oldboy', 'learn': <function OldboyStudent.learn at 0x102a48620>, 'eat': <function OldboyStudent.eat at 0x102a486a8>, '__dict__': <attribute '__dict__' of 'OldboyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'OldboyStudent' objects>, '__doc__': None} 21 oldboy 22 <function OldboyStudent.learn at 0x102a48620> 23 oldboy 24 <function OldboyStudent.learn at 0x102a48620> 25 ''' 26 27 28 res = OldboyStudent.learn(123) #直接调用类的函数方法,需要传参数过去 29 print(type(res)) 30 OldboyStudent.x=1111111111111111111111 31 OldboyStudent.school='Oldboy' 32 del OldboyStudent.school 33 print(OldboyStudent.__dict__) 34 '''is learning 35 <class 'NoneType'> 36 {'__module__': '__main__', 'learn': <function OldboyStudent.learn at 0x102263510>, 'eat': <function OldboyStudent.eat at 0x102263620>, '__dict__': <attribute '__dict__' of 'OldboyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'OldboyStudent' objects>, '__doc__': None, 'x': 1111111111111111111111} 37 '''
对象
类名加括号,调用类,则产生一个该类的实际存在的对象;该调用过程称为实例化,产生的结果也可以称为实例
1.类中的__init__函数:每个对象会有其自己独有的属性,就需要在init中来定义
2.实例化对象分为两步:第一步:生成一个空对象 第二步:空对象和其独有的数据属性作为参数调用init函数
#产生程序中的对象:类名加括号,调用类,产生一个该类的实际存在的对象,该调用过程称为实例化,产生的结果又可以成为实例 class PythonStudent: school = 'python' def __init__(self,name,age,sex): #在实例化时,产生对象之后执行 # if not isinstance(name,str): # raise TypeError('名字必须是字符串类型') self.name=name self.age=age self.sex=sex # return None #__init__方法必须返回None def learn(self): print('is learning') def eat(self): print('is eating') obj1=PythonStudent('zyl',18,'女') # 分两步: # 第一步:先产生一个空对象obj1 # 第二步:OldboyStudent.__init__(obj1,'zyl',18,'女') print(obj1.__dict__) '''{'name': 'zyl', 'age': 18, 'sex': '女'}''' #通过对象操作类的属性 print(obj1.name)#obj1.__dict__['name'] #zyl obj1.name = 'lingling' print(obj1.__dict__['name']) #lingling obj1.__dict__.pop('name') print(obj1.__dict__) #{'age': 18, 'sex': '女'}
3.类的数据属性是所有该类的对象共享的,id都一样
4.类的对象不可以方位该类之前的名称空间
5.对象访问类的方法,通过绑定方法实现访问;会直接把对象自身作为参数传递给类的方法
6.绑定方法:绑定给谁就有谁来调用;谁来调用就把谁本身作为第一个参数传入
1 school = 'test' 2 class PythonStudent: 3 school = 'python' 4 def __init__(self,name,age,sex): #在实例化时,产生对象之后执行 5 # if not isinstance(name,str): 6 # raise TypeError('名字必须是字符串类型') 7 self.name=name 8 self.age=age 9 self.sex=sex 10 # return None #__init__方法必须返回None 11 def learn(self): 12 print('is learning') 13 14 def eat(self): 15 print('is eating') 16 17 obj1=PythonStudent('zyl',18,'女') 18 print(obj1.school) #类的对象只能操作类的属性,不能操作类之外的属性 19 '''python''' 20 obj2=PythonStudent('zyl1',13,'女') 21 obj3=PythonStudent('zyl2','12','女') 22 23 #对象可以访问类的数据属性,结论:类的数据属性共享给所有对象使用,id对一样 24 print(obj1.school,id(obj1.school)) 25 print(obj2.school,id(obj2.school)) 26 print(obj3.school,id(obj3.school)) 27 print(PythonStudent.school,id(PythonStudent.school)) 28 '''python 4329986512 29 python 4329986512 30 python 4329986512 31 python 4329986512''' 32 33 #类的函数属性是绑定给所有对象使用的,绑定给不同的对象是不同的绑定方法,绑定方法有何特殊之处? 34 #暂且抛开绑定方法,类肯定可以访问自己的函数属性 35 PythonStudent.learn(obj1) 36 PythonStudent.learn(obj2) 37 PythonStudent.learn(obj3) 38 '''is learning 39 is learning 40 is learning''' 41 print(obj1.learn) 42 print(obj2.learn) 43 print(obj3.learn) 44 print(PythonStudent.learn) 45 '''<bound method PythonStudent.learn of <__main__.PythonStudent object at 0x1022419b0>> 46 <bound method PythonStudent.learn of <__main__.PythonStudent object at 0x102241a58>> 47 <bound method PythonStudent.learn of <__main__.PythonStudent object at 0x102241a90>> 48 <function PythonStudent.learn at 0x102248620> 49 ''' 50 51 #绑定方法:绑定给谁,就由谁来调用,谁来调用就把“谁”本身当做第一个参数传入 52 obj1.learn() #PythonStudent.learn(obj1) 53 obj2.learn() #PythonStudent.learn(obj1) 54 obj3.learn() #PythonStudent.learn(obj1)
7.python中类型即是类
1 #在python3中类型就类 2 print(PythonStudent) 3 print(list) 4 5 l1=list() 6 print(type(l1)) 7 8 # l1.append(3) #list.append(l1,3) 9 list.append(l1,3) 10 print(l1) 11 '''<class '__main__.PythonStudent'> 12 <class 'list'> 13 <class 'list'> 14 [3]'''
8.属性查找顺序:先从对象的__dict__中查找,再对象的类的__dict__;然后是类的父类。。。。
PythonStudent.school='哈佛' obj1.school='hahahahahahahhahahahahahah' print(obj1.__dict__) print(obj1.school) print(obj2.school) print(obj3.school) ‘’‘{'name': 'zyl', 'age': 18, 'sex': '女', 'school': 'hahahahahahahhahahahahahah'} hahahahahahahhahahahahahah 哈佛 哈佛’‘’
9.小程序
1 #实例化一次计数加1,可以在类的数据属性中定义一个变量,所有的对象共享该数据属性;然后在init的对象属性中调用在类的数据属性 2 class Foo: 3 count=0 4 def __init__(self,x,y,z): 5 self.x=x 6 self.y=y 7 self.z=z 8 Foo.count+=1 9 obj1=Foo(1,1,1) 10 obj2=Foo(1,2,1) 11 obj3=Foo(1,2,3) 12 13 print(obj1.count) 14 print(Foo.count) 15 '''3 16 3'''
10.对象之间的交互
1 class Garen: 2 camp='Demacia' 3 def __init__(self,nickname,life_value=100,aggresivity=80): 4 self.nickname=nickname 5 self.life_value=life_value 6 self.aggresivity=aggresivity 7 def attack(self,enemy): 8 enemy.life_value-=self.aggresivity 9 10 class Riven: 11 camp = 'Noxus' 12 def __init__(self, nickname, life_value=90, aggresivity=100): 13 self.nickname = nickname 14 self.life_value = life_value 15 self.aggresivity = aggresivity 16 17 def attack(self, enemy): 18 enemy.life_value -= self.aggresivity 19 20 21 g1=Garen('gname') 22 r1=Riven('rname') 23 24 print(r1.life_value) 25 g1.attack(r1) 26 print(r1.life_value) 27 '''90 28 10'''
三、类的继承
1.继承的基本形式
2.classname.__bases__可以查看父类
1 #继承的基本形式 2 class ParentClass1(object): #定义父类 3 pass 4 5 class ParentClass2: #定义父类 6 pass 7 8 class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass 9 pass 10 11 class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类 12 pass 13 14 print(ParentClass2.__bases__) 15 print(ParentClass1.__bases__) 16 print(SubClass1.__bases__) 17 print(SubClass2.__bases__) 18 '''(<class 'object'>,) 19 (<class 'object'>,) 20 (<class '__main__.ParentClass1'>,) 21 (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)'''
3.经典类与新式类的区别
#python3都是新式类,默认会继承object
#python2继承了object就是新式类,不继承object就是经典类
4.类的继承;通过类调用其方法,复用父类中init的数据属性
1 class Animal: 2 x=1 3 def __init__(self,name,age,sex): 4 self.name=name 5 self.age=age 6 self.sex=sex 7 # print('Animal.__init__') 8 def eat(self): 9 print('%s eat' %self.name) 10 11 def talk(self): 12 print('%s say' %self.name) 13 14 class People(Animal): 15 x=10 16 def __init__(self,name,age,sex,education): 17 Animal.__init__(self,name,age,sex) #父类调用其init方法,复用父类中的数据属性 18 self.education=education 19 # print('People.__init__') 20 21 def talk(self): 22 Animal.talk(self) 23 print('这是人在说话') 24 25 class Dog(Animal): 26 pass 27 class Pig(Animal): 28 pass 29 30 31 peo1=People('teser',18,'male','小学肄业') 32 print(peo1.__dict__) 33 peo1.talk() 34 print(peo1.x) #寻找属性顺序:先对象属性;在对应类属性;然后父类属性 35 36 dog1=Dog('yuanhao',28,'male') 37 pig1=Pig('wupeiqi',18,'male') 38 39 print(peo1.name) 40 print(dog1.name) 41 print(pig1.name) 42 43 '''{'name': 'teser', 'age': 18, 'sex': 'male', 'education': '小学肄业'} 44 teser say 45 这是人在说话 46 10 47 teser 48 yuanhao 49 wupeiqi'''
5.总结
'''
1) 继承的功能之一:解决类与类之间的代码重复问题
2 )继承是类与类之间的关系,是一种,什么是什么的关系
3 )在子类派生出的新的属性,以自己的为准
4) 在子类派生出的新的方法内重用父类的功能的方式:指名道姓法OldboyPeople.__init__这种调用方式本身与继承是没有关系
'''
1 class OldboyPeople: 2 school = 'oldboy' 3 def __init__(self,name,age,sex): 4 self.name=name 5 self.age=age 6 self.sex=sex 7 8 def eat(self): 9 print('is eating') 10 11 class OldboyStudent(OldboyPeople): 12 def learn(self): 13 print('%s is learning' %self.name) 14 15 16 class OldboyTeacher(OldboyPeople): 17 def __init__(self,name,age,sex,salary,title): 18 OldboyPeople.__init__(self,name,age,sex) 19 self.salary=salary 20 self.title=title 21 22 def teach(self): 23 print('%s is teaching' %self.name) 24 25 26 yl_obj=OldboyStudent('yanglei',28,'female') 27 egon_obj=OldboyTeacher('egon',18,'male',3.1,'沙河霸道金牌讲师') 28 29 # 30 yl_obj.learn() 31 yl_obj.eat() 32 33 print(egon_obj.__dict__)
6.组合
1 class OldboyPeople: 2 school = 'oldboy' 3 def __init__(self,name,age,sex): 4 self.name=name 5 self.age=age 6 self.sex=sex 7 8 def eat(self): 9 print('is eating') 10 11 class OldboyStudent(OldboyPeople): 12 13 def __init__(self,name,age,sex): 14 OldboyPeople.__init__(self,name,age,sex) 15 self.course=[] 16 17 def learn(self): 18 print('%s is learning' %self.name) 19 20 21 class OldboyTeacher(OldboyPeople): 22 def __init__(self,name,age,sex,salary,title): 23 OldboyPeople.__init__(self,name,age,sex) 24 self.salary=salary 25 self.title=title 26 self.course=[] 27 28 def teach(self): 29 print('%s is teaching' %self.name) 30 31 32 class Course: 33 def __init__(self,course_name,course_period,course_price): 34 self.course_name=course_name 35 self.course_period=course_period 36 self.course_price=course_price 37 def tell_info(self): 38 print('<课程名:%s 周期:%s 价格:%s>' %(self.course_name,self.course_period,self.course_price)) 39 40 python=Course('Python','6mons',3000) 41 linux=Course('Lnux','3mons',2000) 42 bigdata=Course('BigData','1mons',1000) 43 44 # python.tell_info() 45 46 47 egon_obj=OldboyTeacher('egon',18,'male',3.1,'沙河霸道金牌讲师') 48 # 49 # egon_obj.course.append(python) 50 # egon_obj.course.append(linux) 51 # 52 # for obj in egon_obj.course: 53 # obj.tell_info() 54 55 56 yl_obj=OldboyStudent('yanglei',28,'female') 57 yl_obj.course.append(python) 58 59 for i in yl_obj.course: 60 # print(i.course_name,i.course_period,i.course_price) 61 i.tell_info()
7.子类的方法复用父类功能:super
super()__init__(args) #python3中使用形式
super(parentclass,self).__init__(args) #python2中需要写父类名称和self
class OldboyPeople: school = 'oldboy' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def eat(self): print('is eating') def teach(self): print('这是父类的teach') class OldboyTeacher(OldboyPeople): def __init__(self,name,age,sex,salary,title): # OldboyPeople.__init__(self,name,age,sex) #在Python2中需要写全:super(OldboyTeacher,self) super().__init__(name,age,sex) self.salary=salary self.title=title def teach(self): # OldboyPeople.teach(self) super().teach() print('%s is teaching' %self.name) egon_obj=OldboyTeacher('egon',18,'male',3.1,'沙河霸道金牌讲师') egon_obj.teach() print(OldboyTeacher.mro()) #classname.mro()属性查找顺序,也是super的复用父类顺序
8.类名.mro()是查找复用父类的顺序
1 class A: 2 def test(self): 3 super().test() 4 5 class B: 6 def test(self): 7 print('B') 8 9 class C(A,B): 10 pass 11 12 a=A() 13 a.test() 14 '''AttributeError: 'super' object has no attribute 'test' 15 ''' 16 17 print(C.mro()) 18 c=C() 19 c.test() 20 '''[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>] 21 B'''
四、绑定方法和非绑定方法
1.类的绑定
1 import settings 2 ''' 3 settings参数: 4 HOST='192.168.31.1' 5 PORT=3106 6 ''' 7 8 class MySql: 9 def __init__(self,host,port): 10 self.host=host 11 self.port=port 12 13 @classmethod 14 def from_conf(cls): 15 print(cls) #<class '__main__.MySql'> 16 return cls(settings.HOST,settings.PORT) 17 18 def func1(self):pass 19 20 21 conn1=MySql('127.0.0.1',3306) 22 23 conn2=MySql.from_conf() 24 print(conn1.host,conn2.host) 25 ''' 26 127.0.0.1 27 192.168.31.1''' 28 29 # print(conn1.func1) 30 # print(conn1.from_conf) 31 # print(MySql.from_conf) 32 '''<bound method MySql.func1 of <__main__.MySql object at 0x10225c898>> 33 <bound method MySql.from_conf of <class '__main__.MySql'>> 34 <bound method MySql.from_conf of <class '__main__.MySql'>>''' 35 36 conn1.from_conf() 37 MySql.from_conf() 38 '''<class '__main__.MySql'> 39 <class '__main__.MySql'>'''
2.不绑定
1 import settings 2 import uuid 3 class MySql: 4 def __init__(self,host,port): 5 self.host=host 6 self.port=port 7 self.id=self.create_id() 8 9 @classmethod 10 def from_conf(cls): #绑定给类的 11 print(cls) 12 # return cls(settings.HOST,settings.PORT) 13 14 def func1(self): #绑定给对象的 15 pass 16 17 @staticmethod 18 def create_id(): #非绑定方法 19 return str(uuid.uuid1()) 20 21 22 conn1=MySql('127.0.0.1',3306) 23 conn2=MySql('127.0.0.2',3306) 24 conn3=MySql('127.0.0.3',3306) 25 print(MySql.create_id) 26 print(conn1.create_id) 27 28 print(conn1.id,conn2.id,conn3.id) 29 '''<function MySql.create_id at 0x102345268> 30 <function MySql.create_id at 0x102345268> 31 5f9bd05c-801e-11e7-9afc-dca90483a918 5fa0cf8a-801e-11e7-a32f-dca90483a918 5fa0d05c-801e-11e7-aeee-dca90483a918'''