一、面向过程与面向对象的优缺点
面向过程
优点:复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤区实现)
缺点:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生成骑车,即便是能,也得是大改,改一个组件牵多整个项目。
面向对象
优点:解决程序的扩展性,对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中的一个人物参数的特征和技能修改都很容易。
缺点:编程的复杂度远高于面向过程;无法面向过程的程序设计流水线式的可以很精准的预测问题得处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法准确地预测结果。
二、类与对象
在生活中:现有对象再有类,类仅仅只是一个概念,并不真实存在。
在程序中:务必保证先定义类,后产生对象。
1 #在程序中,务必保证:先定义(类),后使用(产生对象) 2 PS: 3 1. 在程序中特征用变量标识,技能用函数标识 4 2. 因而类中最常见的无非是:变量和函数的定义 5 6 #程序中的类 7 class OldboyStudent: 8 school='oldboy' 9 def learn(self): 10 print('is learning') 11 12 def eat(self): 13 print('is eating') 14 15 def sleep(self): 16 print('is sleeping') 17 18 19 20 #注意: 21 1.类中可以有任意python代码,这些代码在类定义阶段便会执行 22 2.因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过OldboyStudent.__dict__查看 23 3.对于经典类来说我们可以通过该字典操作类名称空间的名字(新式类有限制),但python为我们提供专门的.语法 24 4.点是访问属性的语法,类中定义的名字,都是类的属性 25 26 #程序中类的用法 27 .:专门用来访问属性,本质操作的就是__dict__ 28 OldboyStudent.school #等于经典类的操作OldboyStudent.__dict__['school'] 29 OldboyStudent.school='Oldboy' #等于经典类的操作OldboyStudent.__dict__['school']='Oldboy' 30 OldboyStudent.x=1 #等于经典类的操作OldboyStudent.__dict__['x']=1 31 del OldboyStudent.x #等于经典类的操作OldboyStudent.__dict__.pop('x') 32 33 34 #程序中的对象 35 #调用类,或称为实例化,得到对象 36 s1=OldboyStudent() 37 s2=OldboyStudent() 38 s3=OldboyStudent() 39 40 #如此,s1、s2、s3都一样了,而这三者除了相似的属性之外还各种不同的属性,这就用到了__init__ 41 #注意:该方法是在对象产生之后才会执行,只用来为对象进行初始化操作,可以有任意代码,但一定不能有返回值 42 class OldboyStudent: 43 ...... 44 def __init__(self,name,age,sex): 45 self.name=name 46 self.age=age 47 self.sex=sex 48 ...... 49 50 51 s1=OldboyStudent('李坦克','男',18) #先调用类产生空对象s1,然后调用OldboyStudent.__init__(s1,'李坦克','男',18) 52 s2=OldboyStudent('王大炮','女',38) 53 s3=OldboyStudent('牛榴弹','男',78) 54 55 56 #程序中对象的用法 57 #执行__init__,s1.name='牛榴弹',很明显也会产生对象的名称空间 58 s2.__dict__ 59 {'name': '王大炮', 'age': '女', 'sex': 38} 60 61 s2.name #s2.__dict__['name'] 62 s2.name='王三炮' #s2.__dict__['name']='王三炮' 63 s2.course='python' #s2.__dict__['course']='python' 64 del s2.course #s2.__dict__.pop('course')
1 #1、在没有学习类这个概念时,数据与功能是分离的 2 def exc1(host,port,db,charset): 3 conn=connect(host,port,db,charset) 4 conn.execute(sql) 5 return xxx 6 7 8 def exc2(host,port,db,charset,proc_name) 9 conn=connect(host,port,db,charset) 10 conn.call_proc(sql) 11 return xxx 12 13 #每次调用都需要重复传入一堆参数 14 exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;') 15 exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字') 16 17 18 19 20 #2、我们能想到的解决方法是,把这些变量都定义成全局变量 21 HOST=‘127.0.0.1’ 22 PORT=3306 23 DB=‘db1’ 24 CHARSET=‘utf8’ 25 26 def exc1(host,port,db,charset): 27 conn=connect(host,port,db,charset) 28 conn.execute(sql) 29 return xxx 30 31 32 def exc2(host,port,db,charset,proc_name) 33 conn=connect(host,port,db,charset) 34 conn.call_proc(sql) 35 return xxx 36 37 exc1(HOST,PORT,DB,CHARSET,'select * from tb1;') 38 exc2(HOST,PORT,DB,CHARSET,'存储过程的名字') 39 40 41 #3、但是2的解决方法也是有问题的,按照2的思路,我们将会定义一大堆全局变量,这些全局变量并没有做任何区分,即能够被所有功能使用,然而事实上只有HOST,PORT,DB,CHARSET是给exc1和exc2这两个功能用的。言外之意:我们必须找出一种能够将数据与操作数据的方法组合到一起的解决方法,这就是我们说的类了 42 43 class MySQLHandler: 44 def __init__(self,host,port,db,charset='utf8'): 45 self.host=host 46 self.port=port 47 self.db=db 48 self.charset=charset 49 def exc1(self,sql): 50 conn=connect(self.host,self.port,self.db,self.charset) 51 res=conn.execute(sql) 52 return res 53 54 55 def exc2(self,sql): 56 conn=connect(self.host,self.port,self.db,self.charset) 57 res=conn.call_proc(sql) 58 return res 59 60 61 obj=MySQLHandler('127.0.0.1',3306,'db1') 62 obj.exc1('select * from tb1;') 63 obj.exc2('存储过程的名字') 64 65 66 #改进 67 class MySQLHandler: 68 def __init__(self,host,port,db,charset='utf8'): 69 self.host=host 70 self.port=port 71 self.db=db 72 self.charset=charset 73 self.conn=connect(self.host,self.port,self.db,self.charset) 74 def exc1(self,sql): 75 return self.conn.execute(sql) 76 77 def exc2(self,sql): 78 return self.conn.call_proc(sql) 79 80 81 obj=MySQLHandler('127.0.0.1',3306,'db1') 82 obj.exc1('select * from tb1;') 83 obj.exc2('存储过程的名字')
三、属性查找
类有两种属性:数据属性和函数属性
1、类的数据属性是所有对象共享的
2、类的函数属性是绑定给对象用的
1 #类的数据属性是所有对象共享的,id都一样 2 print(id(OldboyStudent.school)) 3 4 print(id(s1.school)) 5 print(id(s2.school)) 6 print(id(s3.school)) 7 8 ''' 9 4377347328 10 4377347328 11 ''' 12 13 14 15 #类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不一样 16 #ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准 17 print(OldboyStudent.learn) 18 print(s1.learn) 19 print(s2.learn) 20 print(s3.learn) 21 ''' 22 <function OldboyStudent.learn at 0x1021329d8> 23 <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x1021466d8>> 24 <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146710>> 25 <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146748>> 26 '''
在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常
待完善~~