python面向对象(一)
什么是面向对象的程序设计及为什么要有它
面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式。
优点是:复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现,实现小的步骤将会非常简单)
缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身。
应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。
面向对象的程序设计:核心是对象二字,(要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的数据属性和方法属性),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙交互着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取),对象是特征与技能的结合体,基于面向对象设计程序就好比在创造一个世界,你就是这个世界的上帝,存在的皆为对象,不存在的也可以创造出来,与面向过程机械式的思维方式形成鲜明对比,面向对象更加注重对现实世界的模拟,是一种“上帝式”的思维方式。
优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
缺点:
1. 编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题。一些扩展性要求低的场景使用面向对象会徒增编程难度,比如管理linux系统的shell脚本就不适合用面向对象去设计,面向过程反而更加适合。
2. 无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法准确地预测最终结果。于是我们经常看到对战类游戏,新增一个游戏人物,在对战的过程中极容易出现阴霸的技能,一刀砍死3个人,这种情况是无法准确预知的,只有对象之间交互才能准确地知道最终的结果。
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方
面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。
类与对象
类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体
那么问题来了,先有的一个个具体存在的对象(比如一个具体存在的人),还是先有的人类这个概念,这个问题需要分两种情况去看
在现实世界中:先有对象,再有类
世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,如人类、动物类、植物类等概念
也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在
在程序中:务必保证先定义类,后产生对象
这与函数的使用是类似的,先定义函数,后调用函数,类也是一样的,在程序中需要先定义类,后调用类
不一样的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象
按照上述步骤,我们来定义一个类
在现实世界中:先有对象,再有类
对象1:李坦克 特征: 学校=北京大学 姓名=李坦克 性别=男 年龄=18 技能: 学习 吃饭 睡觉
对象2:王大炮 特征: 学校=beijing 姓名=北京大学 性别=女 年龄=38 技能: 学习 吃饭 睡觉
现实中的北京大学学生类 相似的特征: 学校=北京大学 相似的技能: 学习 吃饭 睡觉
在程序中:先定义类,后产生对象
#在程序中,务必保证:先定义(类),后使用(产生对象)PS: 1. 在程序中特征用变量标识,技能用函数标识 2. 因而类中最常见的无非是:变量和函数的定义
#程序中的类class BeiJingStudent: school='oldboy' def learn(self): print('is learning') def eat(self): print('is eating') def sleep(self): print('is sleeping') #注意: 1.类中可以有任意python代码,这些代码在类定义阶段便会执行 2.因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过BeiJingStudent.__dict__查看 3.对于经典类来说我们可以通过该字典操作类名称空间的名字(新式类有限制),但python为我们提供专门的.语法 4.点是访问属性的语法,类中定义的名字,都是类的属性
#程序中类的用法.:专门用来访问属性,本质操作的就是__dict__BeiJingStudent.school #等于经典类的操作BeiJingStudent.__dict__['school']BeiJingStudent.school='Oldboy' #等于经典类的操作BeiJingStudent.__dict__['school']='Oldboy'BeiJingStudent.x=1 #等于经典类的操作BeiJingStudent.__dict__['x']=1del BeiJingStudent.x #等于经典类的操作BeiJingStudent.__dict__.pop('x')
#程序中的对象#调用类,或称为实例化,得到对象s1=BeiJingStudent()s2=BeiJingStudent()s3=BeiJingStudent()
#如此,s1、s2、s3都一样了,而这三者除了相似的属性之外还各种不同的属性,这就用到了__init__#注意:该方法是在对象产生之后才会执行,只用来为对象进行初始化操作,可以有任意代码,但一定不能有返回值class BeiJingStudent: ...... def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex ......s1=BeiJingStudent('李坦克','男',18) #先调用类产生空对象s1,然后调用BeiJingStudent.__init__(s1,'李坦克','男',18)s2=BeiJingStudent('王大炮','女',38)s3=BeiJingStudent('牛榴弹','男',78)#程序中对象的用法#执行__init__,s1.name='牛榴弹',很明显也会产生对象的名称空间s2.__dict__{'name': '王大炮', 'age': '女', 'sex': 38}
s2.name #s2.__dict__['name']s2.name='王三炮' #s2.__dict__['name']='王三炮's2.course='python' #s2.__dict__['course']='python'del s2.course #s2.__dict__.pop('course')
细说__init__方法
#方式一、为对象初始化自己独有的特征class People: country='China' x=1 def run(self): print('----->', self)
# 实例化出三个空对象obj1=People()obj2=People()obj3=People()
# 为对象定制自己独有的特征obj1.name='egon'obj1.age=18obj1.sex='male'
obj2.name='lxx'obj2.age=38obj2.sex='female'
obj3.name='alex'obj3.age=38obj3.sex='female'
# print(obj1.__dict__)# print(obj2.__dict__)# print(obj3.__dict__)# print(People.__dict__)
#方式二、为对象初始化自己独有的特征class People: country='China' x=1 def run(self): print('----->', self)
# 实例化出三个空对象obj1=People()obj2=People()obj3=People()
# 为对象定制自己独有的特征def chu_shi_hua(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male' obj.name = x obj.age = y obj.sex = z
chu_shi_hua(obj1,'egon',18,'male')chu_shi_hua(obj2,'lxx',38,'female')chu_shi_hua(obj3,'alex',38,'female')
#方式三、为对象初始化自己独有的特征class People: country='China' x=1
def chu_shi_hua(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male' obj.name = x obj.age = y obj.sex = z
def run(self): print('----->', self)
obj1=People()# print(People.chu_shi_hua)People.chu_shi_hua(obj1,'egon',18,'male')
obj2=People()People.chu_shi_hua(obj2,'lxx',38,'female')
obj3=People()People.chu_shi_hua(obj3,'alex',38,'female')
# 方式四、为对象初始化自己独有的特征class People: country='China' x=1
def __init__(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male' obj.name = x obj.age = y obj.sex = z
def run(self): print('----->', self)
obj1=People('egon',18,'male') #People.__init__(obj1,'egon',18,'male')obj2=People('lxx',38,'female') #People.__init__(obj2,'lxx',38,'female')obj3=People('alex',38,'female') #People.__init__(obj3,'alex',38,'female')
# __init__方法# 强调:# 1、该方法内可以有任意的python代码# 2、一定不能有返回值class People: country='China' x=1
def __init__(obj, name, age, sex): #obj=obj1,x='egon',y=18,z='male' # if type(name) is not str: # raise TypeError('名字必须是字符串类型') obj.name = name obj.age = age obj.sex = sex
def run(self): print('----->', self)
# obj1=People('egon',18,'male')obj1=People(3537,18,'male')
# print(obj1.run)# obj1.run() #People.run(obj1)# print(People.run)
补充
1. 站的角度不同,定义出的类是截然不同的,详见面向对象实战之需求分析
2. 现实中的类并不完全等于程序中的类,比如现实中的公司类,在程序中有时需要拆分成部门类,业务类......
3. 有时为了编程需求,程序中也可能会定义现实中不存在的类,比如策略类,现实中并不存在,但是在程序中却是一个很常见的类
类的特殊属性
#python为类内置的特殊属性类名.__name__# 类的名字(字符串)类名.__doc__# 类的文档字符串类名.__base__# 类的第一个父类(在讲继承时会讲)类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)类名.__dict__# 类的字典属性类名.__module__# 类定义所在的模块类名.__class__# 实例对应的类(仅新式类中)
类的特殊属性(了解即可)
数据与专门操作该数据的功能组合到一起
#1、在没有学习类这个概念时,数据与功能是分离的def exc1(host,port,db,charset): conn=connect(host,port,db,charset) conn.execute(sql) return xxx
def exc2(host,port,db,charset,proc_name) conn=connect(host,port,db,charset) conn.call_proc(sql) return xxx
#每次调用都需要重复传入一堆参数exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;')exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字')
#2、我们能想到的解决方法是,把这些变量都定义成全局变量HOST=‘127.0.0.1’PORT=3306DB=‘db1’CHARSET=‘utf8’
def exc1(host,port,db,charset): conn=connect(host,port,db,charset) conn.execute(sql) return xxx
def exc2(host,port,db,charset,proc_name) conn=connect(host,port,db,charset) conn.call_proc(sql) return xxx
exc1(HOST,PORT,DB,CHARSET,'select * from tb1;')exc2(HOST,PORT,DB,CHARSET,'存储过程的名字')
#3、但是2的解决方法也是有问题的,按照2的思路,我们将会定义一大堆全局变量,这些全局变量并没有做任何区分,即能够被所有功能使用,然而事实上只有HOST,PORT,DB,CHARSET是给exc1和exc2这两个功能用的。言外之意:我们必须找出一种能够将数据与操作数据的方法组合到一起的解决方法,这就是我们说的类了
class MySQLHandler: def __init__(self,host,port,db,charset='utf8'): self.host=host self.port=port self.db=db self.charset=charset def exc1(self,sql): conn=connect(self.host,self.port,self.db,self.charset) res=conn.execute(sql) return res
def exc2(self,sql): conn=connect(self.host,self.port,self.db,self.charset) res=conn.call_proc(sql) return res
obj=MySQLHandler('127.0.0.1',3306,'db1')obj.exc1('select * from tb1;')obj.exc2('存储过程的名字')
#改进class MySQLHandler: def __init__(self,host,port,db,charset='utf8'): self.host=host self.port=port self.db=db self.charset=charset self.conn=connect(self.host,self.port,self.db,self.charset) def exc1(self,sql): return self.conn.execute(sql)
def exc2(self,sql): return self.conn.call_proc(sql)
obj=MySQLHandler('127.0.0.1',3306,'db1')obj.exc1('select * from tb1;')obj.exc2('存储过程的名字')
识别图中二维码,领取python全套视频资料
python面向对象(一)的更多相关文章
- python 面向对象初级篇
Python 面向对象(初级篇) 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发" ...
- Python 面向对象 基础
编程范式概述:面向过程 和 面向对象 以及函数式编程 面向过程:(Procedure Oriented)是一种以事件为中心的编程思想. 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现 ...
- python面向对象进阶(八)
上一篇<Python 面向对象初级(七)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...
- python 面向对象(进阶篇)
上一篇<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...
- python 面向对象编程学习
1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...
- Python面向对象详解
Python面向对象的"怜人之处" Python的待客之道--谁能进来 Python的封装--只给你想要的 Python的继承--到处认干爹 Python的多态--说是就是
- python 面向对象和类成员和异常处理
python 面向对象 你把自己想象成一个上帝,你要创造一个星球,首先你要把它揉成一个个球,两个直径就能创造一个球 class star: '''名字(name),赤道直径(equatorial di ...
- python 面向对象学习
------Python面向对象初 下面写一个类的简单实用,以便方便理解类 #python 3.5环境,解释器在linux需要改变 #阅读手册查询readme文件 #作者:S12-陈金彭 class ...
- 初识python面向对象
一.初识python面向对象: class Person: #使用class关键字定义一个类 age=0 #类变量(静态变量) def eat(self,food): #定义一个方法 self.age ...
- python 面向对象、特殊方法与多范式、对象的属性及与其他语言的差异
1.python 面向对象 文章内容摘自:http://www.cnblogs.com/vamei/archive/2012/06/02/2532018.html 1.__init__() 创建对 ...
随机推荐
- js实现仿购物车加减效果
代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <tit ...
- javascript学习笔记(三)
1.与命名空间相关的方法以及属性 2.任何支持style特性的HTML元素在Javascript中都有一个对应的style属性.这个属性是CSSStyleDecalration的实例, 包含着通过HT ...
- asp.net core mvc视频A:笔记6-1.应用发布与部署
显示:直接使用上节课的项目 一.使用vs发布应用 这里选择发布到文件夹,当然你可以选择其他的发布方式 部署模式:(我的VS里没有这个配置,不知道为啥...视频里有) 1.框架依赖:选择此模式,发布后需 ...
- 【C#】重载重写重构
前言 前几篇博客说了重写和重载.今天主要说重构,顺便比較一下三者. 重构.重写.重载 重构就是通过调整程序代码改善软件的质量.性能,使其程序的设计模式和架构更趋合理.提高软件的扩展性和维护性. 通俗点 ...
- rocketmq发送消息代码
DefaultMQProducer defaultMQProducer = new DefaultMQProducer(); defaultMQProducer.setProducerGroup(Co ...
- UML类图详解_泛化关系
泛化其实就是继承关系,还是比较简单的,那么我们就把之前有些问题的博客UML类图重新来实现一次. 依旧是这个图 下面我们来看一个例子 Account.h #include <cstdlib> ...
- 手游后台PVP系统网络同步方案总结
游戏程序 平台类型: 程序设计: 编程语言: 引擎/SDK: 概述 PVP系统俨然成为现在新手游的上线标配,手游Pvp系统体验是否优秀,很大程度上决定了游戏的品质.从最近半年上线的新手 ...
- 使用加密的squid配合stunnel实现HTTP代理
现在大部分人都是用ssh tunnel来搭建socks5代理,其实这种方式效率并不高,ssh tunnel并不是为了做代理而存在的.一个比较好的方法是加密squid配合stunnel实现http代理. ...
- 依赖Spring的情况下,Java Web项目如何在启动时加载数据库中的数据?
原文:https://blog.csdn.net/u012345283/article/details/39558537 原文:https://blog.csdn.net/wandrong/artic ...
- AV1视频编码标准资源汇总
一直不看好HEVC,总觉得这东西绝对不可能再恢复像h264那么辉煌了,如此高昂的授权费,被淘汰估计也就这一两年了,有必要预研一下AV1,马上进去二进制码流冻结流程了,感觉aom越来越近了,毕竟goog ...