开篇

面向过程编程和面向对象编程是两种基本的编程思想。

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:1097524789

在这之前,你学习到的都是面向过程编程,即:首先分析出解决问题的每个步骤 ,然后编写函数实现每个步骤,最后通过合适的顺序依次调用函数来解决问题。

不同于面向过程编程,面向对象编程的思想其实是从自然界的机理中借鉴而来的。正所谓物以类聚,在渺渺的大自然中,有数不胜数的类别,按照不同的星球来分类,可以分为:地球类、太阳类、火星类、月球类、海王星类等等

按照地球上的不同形态的生命,可以分为植物类、动物类、细菌类等等


你还可以按照自己的喜好,划分出自己的分类标准。

使用面向对象编程,可以让你站在一个更高的视角来审视问题,此时,你所解决的不仅仅是一个问题,而是一类问题。

对比面向过程,初识面向对象

在介绍各种概念之前,让我们先做一个小栗子,通过对比面向过程编程的方式去感受面向对象编程的奥妙。

栗子如下:

小明家里养了3只小猫,每到中午饭点,这三只小猫便要吃饭了。吃饭前,小猫们都会 先洗手,然后喵喵叫三声。请写一个程序,来分别模拟这三只小猫完整的吃饭过程,部分细节可自行脑部。

分析问题,可以绘制出解决问题的流程图

如果采用面向过程思想进行编程,可以这样写:

首先分别用函数实现以上流程图中的三个步骤

import time
#模拟吃饭
def eat(number,food):#number:小猫编号,可取1,2,3#food:某编号的小猫所吃食物的名称wash(number)#模拟洗手miao(number)#模拟喵喵叫三声print("{}号小猫正在吃{}".format(number,food))time.sleep(5)#吃饭需要5秒种print('{}号小猫进食完毕,睡觉睡觉咯'.format(number))print()#模拟洗手
def wash(number):#number:小猫编号,可取1,2,3print('{}号小猫正在洗手...'.format(number))time.sleep(3)#洗手花费3秒种print('{}号小猫洗手结束'.format(number))#模拟喵喵叫三声
def miao(number):#number:小猫编号,可取1,2,3print('第{}号小猫喵喵喵~~'.format(number))

有了函数之后,就可以按照合适的序列步骤调用函数来解决问题了:

#模拟第一只小猫的吃饭过程
eat(1,'树叶子')#模拟第二只小猫的吃饭过程
eat(2,'海带丝')#模拟第三只小猫的吃饭过程
eat(3,'石头')

得到如下输出:

1号小猫正在洗手...
1号小猫洗手结束
第1号小猫喵喵喵~~
1号小猫正在吃树叶子
1号小猫进食完毕,睡觉睡觉咯2号小猫正在洗手...
2号小猫洗手结束
第2号小猫喵喵喵~~
2号小猫正在吃海带丝
2号小猫进食完毕,睡觉睡觉咯3号小猫正在洗手...
3号小猫洗手结束
第3号小猫喵喵喵~~
3号小猫正在吃石头
3号小猫进食完毕,睡觉睡觉咯

而若采用面向对象编程,则可以写出如下代码(稍后会对每一句代码进行解释,这里只是先直观感受下面向对象编程的feel):

import time
class CatMeal():#number:小猫编号,可取1,2,3#food:某编号的小猫所吃食物的名称def __init__(self,number,food):self.number=numberself.food=food#模拟吃饭def eat(self):self.wash()self.miao()print("{}号小猫正在吃{}".format(self.number,self.food))time.sleep(5)#吃饭需要5秒种print('{}号小猫进食完毕,睡觉睡觉咯'.format(self.number))print()#模拟洗手def wash(self):#number:小猫编号,可取1,2,3print('{}号小猫正在洗手...'.format(self.number))time.sleep(3)#洗手花费3秒种print('{}号小猫洗手结束'.format(self.number))#模拟喵喵叫三声def miao(self):#number:小猫编号,可取1,2,3print('第{}号小猫喵喵喵~~'.format(self.number))#模拟第一只小猫的吃饭过程
miao1=CatMeal(1,'树叶子')
miao1.eat()##模拟第二只小猫的吃饭过程
miao2=CatMeal(2,'海带丝')
miao2.eat()#模拟第三只小猫的吃饭过程
miao3=CatMeal(3,'石头')
miao3.eat()

得到同样的输出:

1号小猫正在洗手...
1号小猫洗手结束
第1号小猫喵喵喵~~
1号小猫正在吃树叶子
1号小猫进食完毕,睡觉睡觉咯2号小猫正在洗手...
2号小猫洗手结束
第2号小猫喵喵喵~~
2号小猫正在吃海带丝
2号小猫进食完毕,睡觉睡觉咯3号小猫正在洗手...
3号小猫洗手结束
第3号小猫喵喵喵~~
3号小猫正在吃石头
3号小猫进食完毕,睡觉睡觉咯

在上面的代码中,我们使用关键字class定义了一个小猫吃饭的类,名字叫做CatMeal,然后实例化出来了3只小猫,分别模拟了它们吃饭的完整过程。你可能还是对有些代码,比如__init__那里搞不清,没关系,先别着急,在下一部分,我们将详解上述代码,在此之前,有一些东西需要讲一下:

如果你阅读过之前的文章,你会发现,那些文章的思路都是先通过介绍某种方法的不足,然后引出正题,比如由于需要用多个变量来存储多个数字,于是引出了列表这一简单高效的数据结构。在这里,我们先介绍了面向过程的方法,之后才介绍了面向对象的方法,那是不是面向对象比面向过程更具有优势呢?

并不是,这两种编程思想各有千秋。

我们可以按照从简到繁的顺序来捋清这一切:

(1)对于一个非常简单的问题,比如计算两数之和,我们甚至可以直接在命令行中敲下a+b,点击回车即可看到问题的答案:

>>> 1+2
3

(2)接着将问题变复杂些,这次也是计算两数之和,只不过待计算的数值对不止一个,于是我们可以定义一个函数,专门用于做两数之和:

def add(a,b):print('{}+{}={}'.format(a,b,a+b))
#调用函数计算两数之和
>>> add(1,2)
1+2=3

(3)然后,将问题更加复杂化,需要一个简易版计算器,可以用来计算加法和减法,并且要求用户只需输入操作数(待运算的数字,比如1,2,3),而无需输入运算符(比如+,-):

采用面向过程的思想,我们需要定义加法和减法两个函数

def add(a,b):print('{}+{}={}'.format(a,b,a+b))
def minus(a,b):print('{}-{}={}'.format(a,b,a-b))
#调用函数
add(1,2)
minus(2,1)
#输出
1+2=3
2-1=1

而若采用面向对象的思想,我们可以这样写:

class Cal():def add(self,a,b):print('{}+{}={}'.format(a,b,a+b))def minus(self,a,b):print('{}-{}={}'.format(a,b,a-b))

在上面的代码中,我们定义了一个计算类,名字叫做Cal

接下来从这个类中实例化出来一个对象,名字叫做z

#实例化出来一个对象z
z=Cal()#调用方法
z.add(1,2)
z.minus(3,6)

输出结果

1+2=3
3-6=-3

(4)如果现在去除了用户不能输入运算符的限制,那么,使用面向过程编程的代码如下:

def add_or_minus(a,b,op):if op=='+':res=a+belif op=='-':res=a-bprint('{}{}{}={}'.format(a,op,b,res))
#调用
>>> add_or_minus(1,2,'+')
1+2=3
>>> add_or_minus(1,2,'-')
1-2=-1

使用面向对象编程代码如下:

class Cal():def add_or_minus(self,a,b,op):if op=='+':res=a+belif op=='-':res=a-bprint('{}{}{}={}'.format(a,op,b,res))
#实例化类并计算
>>> z=Cal()
>>> z.add_or_minus(1,2,'+')
1+2=3
>>> z.add_or_minus(1,2,'-')
1-2=-1

再次对比这两者,可以看出,面向对象编程给人的感觉是代码变得麻烦了些,而面向过程编程则清爽很多。

原因在于,实现加法和减法是个很简单的问题,在这个问题上使用面向对象的编程方式不能很好的体现出面向对象编程的灵活性和规范性,反而简单的面向过程编程更加易懂、易实现。

在今后,你会看到,当问题规模变大时,面向对象编程将会体现出来显著的优势。

总结来说:面向过程和面向对象这两种编程方式各有千秋,在解决规模较小的问题时使用前者更为方便,而对于大规模问题,后者具有显著优势。当然这也不是绝对的。在性能和维护成本等方面,两者也是不同的。所以,对于不同的应用场景,要学会灵活选用不同的编程方式。

面向对象编程的语法

在这一部分,我们将对之前栗子中面向对象代码进行拆分讲解。

定义一个类

class CatMeal():中:

class是一个Python关键字,表明要定义一个类,它的作用就好比定义函数时用到的关键字def

CatMeal是类的名字,一般约定首字母大写的代表类名,而首字母为小写的代表变量命

在还没有学习后面的内容之前,当你想创建一个新的类时,只需修改类名即可,其余照抄,比如定义一个动物类,可以写class Animal():。当然,在后面的学习中,你会解锁关于这一句代码的更高级用法。

在类中定义方法

我们知道,以关键字def定义的一个代码块叫做函数,用于完成特定的功能。其实,在类里面,也是使用def定义一个代码块,同样是用于完成特定的功能,只不过此时的名字不再是“函数”,而是“方法”(本质上还是函数)。在这个栗子中,定义的__init__eatwashmiao都是方法。

__init__方法默认第一个参数是self(约定俗成的叫法),后面的参数可以自行指定,就像给函数传参那样。

__init__方法里,以参数形式定义特征,称之为属性。

比如本栗中的numberfood就是类中定义的两个属性,你可以类比着添加更多属性。

当然,如果像之前的简易计算器栗子一样,不要求在创建类时手动指定属性,那么就可以不显式地写出__init__方法(可以回看那个栗子来加深理解)。

观察eatwashmiao方法,你会发现,每个方法里面都和__init__方法一样,第一个参数为self

其实,无论是__init__方法也好,其余自定义的方法也罢,它们的第一个参数都必须是self,它代表一个完整的实例化对象。与类相关联的属性和方法都会自动传递给self,通过使用self,可以轻松调用类中的一些属性和方法:

比如在eat方法中,我们传入了self,于是便可以在该方法中使用self.number获取在__init__方法中定义好的number具体值,同理可以使用self.food获取food的具体值。

从类中实例化对象

在编写完成这个CatMeal类之后,便可以通过类来实例化对象了,比如:

miao1=CatMeal(1,'树叶子')

运行这一句代码,会从抽象的类中实例化出来一个对象,名字叫做miao1,同时自动调用__init__方法,并将1树叶子分别传给__init__方法中的numberfood

其内部具体实现过程如下:先在内存中开辟一块空间,然后调用__init__方法,并让self指向那块内存空间,最后让实例化的对象miao1也指向那块内存空间

这个实例化的对象miao1可以通过.来访问类中的属性和调用类中的方法,比如访问food属性,可以写miao1.food;调用wash方法,可以写miao1.wash()

总结

初学者很容易被一堆self所困扰,所以这里尽量使用精炼的语言来总结第二部分所讲内容:

在定义类之后,实例化之前,self这个抽象的东西具有访问类中属性和调用类中方法的权限,所以无论是增加属性,还是增加方法,都离不开self。增加属性可以写self.new_attribute=new_attribute,增加方法可以写

def new_method(self):pass

(可以根据需要自行设定方法中的参数)

比如在定义eatwashmiao方法时,由于还没有实例化对象,因此若要访问类中的属性numberfood,必须借助具有权限的self。因此,每个方法都需要传入self这个参数,以使用self.来进行访问。self仿佛就是一把钥匙。

而在实例化(比如miao1=CatMeal(1,'树叶子'))之后,原先self具有的权限将会复制一份给这个实例化的对象。

之前需要使用self.number来访问number属性,现在依然可以,但同时也支持使用实例化对象.number来进行访问了,比如miao1.number


以上就是本期全部内容了,大家好好消化一下吧

Python面向对象,站在更高的角度来思考相关推荐

  1. 关于对知识的系统建立和站在更高层次进行理解的必要性

    怎么说呢,最近在系统进行学习的有机器人学.拓扑.控制.最优化.虽然对知识进行了系统的归类和整理. 但是还应该站在更高的角度对整个知识体系进行一个概括. 例如最近在学的动力学,就可以将其分为动力学和静力 ...

  2. 刘润:五维思考,让你站得更高、看得更远

    原标题:刘润:五维思考,让你站得更高.看得更远 前言:遇到问题时,有的人很快就能想明白,有的人需要很久才能想明白,还有的人始终都想不明白. 而且,那些很快就能想明白的人,发现不管自己怎么努力,都很难帮 ...

  3. 决胜千里之外:选购优秀邮件服务器 让企业站得更高

    纵观IT技术的快速发展.电子商务国际化愈演愈烈.近几年来,企业邮箱在信息化管理的重要应用及发展潜质,让互联网巨头也纷至沓来,各大邮件服务器软件供应商都已门庭若市.然而,邮件系统种类繁多,各自优劣不同, ...

  4. 站的更高,尿的更远。

    站的更高,尿的更远    骑白马的不一定是王子,他可能是唐僧:带翅膀的也不一定是天使,妈妈说,那是鸟人.     站的更高,尿的更远.   穿别人的鞋,走自己的路,让他们找去吧!   我不是随便的人, ...

  5. python装饰器-如何更通俗地讲解Python的装饰器?

    我从以下几点,由浅入深详细讲解一下Python装饰器:什么是装饰器? 为什么用装饰器? 在哪里用装饰器? 然后以示例+讲解相结合的方式阐述,同时会讲解一些在很多教程和书籍中不会涉及到的内容. 什么是P ...

  6. 匹马行天下之思维决定高度篇——编程“价”更高

    匹马行天下之思维决定高度篇--编程"价"更高 ----也许我注定成不了一个伟大的人,但是至少我可以做一个很棒的自己.我想我现在应该做的不是瞻前顾后,而是活在当下,正确认知自己,做好 ...

  7. C++求复数的角度_【研读.教材分析】“勾股定理”教学——基于单元整体的角度再思考...

    (西安市第八十六中学   刘丽丽) 学科教学要注重知识的"生长点"和"延伸点",把课时知识置于学科整体逻辑体系中,关注结构和通法,处理好局部与整体之间的关系.所 ...

  8. java好还是python好-Python和Java哪个薪资更高、远景更好?

    运用Python的人越来越多,为啥?人工智能浪潮的兴起与TensorFlow以及爬虫结构的普及让Python有了用武之地:大数据与云计算解决方案的运用也为Python的成功猛推了一把.作为数据科学最盛 ...

  9. python和java哪个好-Python和Java哪个薪资更高、远景更好?

    运用Python的人越来越多,为啥?人工智能浪潮的兴起与TensorFlow以及爬虫结构的普及让Python有了用武之地:大数据与云计算解决方案的运用也为Python的成功猛推了一把.作为数据科学最盛 ...

最新文章

  1. 图论刷水题记录(一)(最短路-----dijkstra算法)
  2. c语言程序设计第4版pdf荣政_C语言程序设计(第4版) (史蒂芬.寇肯) 中文pdf扫描版[82MB]...
  3. hdu5442(2015长春网络赛F题)
  4. 【收藏】Hbase2.x协处理器的使用
  5. memc_nginx+srcache_nginx+memcached构建透明的动态页面缓存
  6. 全国计算机等级考试收费不一样,2018年北京全国计算机等级考试收费标准
  7. ISO C99中的一些扩展(草稿)
  8. 反转字符串中的单词 III leetcode
  9. Bash脚本教程之变量
  10. vs写c语言能用scanf,【PAT编写代码时遇到的问题】vs中使用scanf(%c,x);
  11. 代码片段:计算倒计时
  12. JQuery选择器及radio,checkbox,select取值和反选
  13. 广州.NET微软技术俱乐部微信群各位技术大牛的blog
  14. webstorm汉化之后出现乱码现象
  15. 数理逻辑 | 自然演绎规则整理
  16. HDDREG(硬盘坏道修复工具)v1.31绿色版
  17. 汽车诊断仪常用特殊功能-ABS排气
  18. 为什么改了css网页没有变化_「前端开发」HTML/CSS真的好学吗?为什么小胖认为它并没那么简单...
  19. Linux学习资源推荐
  20. 计算机excel操作题考试题目,《计算机考试Excel操作题原题及操作步骤》.doc

热门文章

  1. linux-mv移动更名-硬链接
  2. python-数字数据类型-整数类型-浮点数类型-数据类型间的转换
  3. Mysql 加锁防并发
  4. OpenState之 Mac学习 实验
  5. Shell入门:掌握Linux,OS X,Unix的Shell环境
  6. 不积小流,何以成江海。。。积累
  7. 在循环体中如何实现叠放效果
  8. 面试精讲之面试考点及大厂真题 - 分布式专栏 22 分布式系统下调用链追踪技术
  9. 容器编排技术 -- 使用kubectl实现应用滚动更新
  10. 更改Linux系统的Hostname的四种方式