11. Python语言的核心编程 · 第十一章 Python语言的面向对象(上)

1. 面向对象简介

  Python 是一门 面向对象编程语言
  所谓 面向对象的语言,简单理解就是:语言中的 所有操作 都是通过 对象 来进行的。
  这么解释呢 还是有点抽象,那我们来打几个 比方:你想做件事,你要先去找个 对象;你想要一个 数值,我先找一个 对象 来保存需要的 数值,之后再对 对象 进行调取;你想要一个 字符串,我先找一个 对象 来保存需要的 字符串,之后再对 对象 进行调取;你想要一个 函数,我要先有一个 函数对象 来保存需要的 函数,之后再对 对象 进行调取……回到最初,我们开篇讲的第一句话:Python一切皆对象。这就是对 面向对象的语言 的简单理解。

  在我们进入 面向对象 的世界之前,我们先来对 计算机的编程思想 的发展简单的了解一下。
  面向对象编程思想 是由 面向过程编程思想 在实际操作过程中一步一步的 更新迭代 衍化过来的。那什么是 面向过程 呢?

  面向过程
   面向过程 指将我们的程序 分解 为一个一个的 执行步骤,通过对 每个步骤抽象 来完成程序;

   举个例子:孩子想吃瓜了,怎么办?
     1. 妈妈穿衣服穿鞋出门
     2. 妈妈骑上电动车
     3. 妈妈到超市门口放好电动车
     4. 妈妈西瓜
     5. 妈妈 结账
     6. 妈妈骑电动车回家
     7. 到家孩子吃西瓜

  案例看完了,其实整个的这些步骤如果要编写一成一个 程序,我们一般会按照 面向过程 的编写方法进行编写;从 妈妈穿衣服穿鞋出门 --> 到家孩子吃西瓜 这整个 过程 就是一个 面向过程 的编写思想;这整个事情的 目的 呢,我们需要 7步 来完成实现。我们把实现这个 目的 编写成了 第1步实现什么,第2步实现什么,第3步实现什么……把整个事情分成了一个步骤一个步骤,这就是一个 面向过程 的编写方式;整个这个过程,我们关注的不是“”,不是“东西”……而是“”。
  回到我们现实生活,这整个的步骤和这种生活方式是没什么问题的;但是一旦到了我们 程序 中,我们写完了一段代码不可能就这么完了对吧;更多可能的还是我们还需要 复用 的。假如,这一段代码我们需要 复用 1000次,该怎么办呢?而且我们大家都知道:单纯的 复用 不是最麻烦的,真正麻烦的是程序后期的 更新维护迭代。现在是“妈妈买瓜”;今天妈妈不在家,怎么执行“爸爸买瓜”呢?再或者,外面现在在下暴雨,妈妈不能穿常规衣服去买瓜了,现在妈妈外面需要加套一件“雨衣”,这又该怎么操作呢?等等等等,这是不是每出现一次 需求微调,我们是不是就要 重新编写 代码;这不仅给我带来很多的不方便,更多的是对 代码的正常运行 进行 不断的挑战
  面向过程 这种编写方式往往 只适用一个功能,如果要实现 别的功能 需重新编写新的程序,往往对代码的 复用性 比较
  这种编程方式 符合 人类的思维,编写起来 比较容易
  假设上面这段 代码 我一定要它实现别的功能,比如说 我一定要这段代码 重复1000次,或者说我就是要 “孩子吃肉” 该怎么办?出门左转,小编我是不是刚写完三篇我对 Python语言的函数 的理解;我们把上面这段 代码 放进 函数 里,如果我想 执行1000次 直接调用或者循环 函数 1000次就可以了;我只要改原函数的一行代码,这整个循环的1000次的代码都改了。
  这样的操作没什么问题,而且 函数 的出现也是为了来解决类似的问题而存在的,而单纯 函数 的这个功能仅仅也只是增加的 函数复用性 这一个功能,而上面这个 函数 也只是在做一件事“孩子吃瓜”。如果我想要 “孩子吃肉”、“孩子吃蔬菜”、“孩子吃水果” 该怎么办?它们是不是有很多 相同 或者 相似 的地方;最起码,它整体的运行框架是一致的,只是一些小细节是不一样。讲到这,有些一直追更的读者可能会说:最近的一篇文章 10.Python语言的函数(下) 里刚讲过的 高级函数Python语言的装饰器 来扩展函数的功能;通过 高级函数 来对 孩子 的一些行为进行进行管理;这么操作,虽然需求效果是达到了,但是 高级函数Python语言的装饰器 是否又增加的程序的复杂性;所以,还是前面的那句话:这种编程方式 符合 人类的思维,编写起来 比较容易,但是 功能 比较单一,不利于代码的 复用性

  现在 面向过程 编程编写出来的代码的功能过于单一,用 函数装饰器 进行修改增加的程序的复杂性。那我们还有别的方法吗?

  还是用我们现实生活小事情来作为实例:如果读者朋友你现在是 一家之主,我们什么事都要 操心,指挥别人做这个做那个。你说:孩儿他妈,你出门别忘了穿鞋啊;孩子他妈,你买东西别忘了骑车;孩子他妈,你买了这个瓜别忘了结账……你是操碎了心,对吧?你这个孩他妈去买东西不能明抢对吧,我还是要结账的对吧。所以,你这样子在家肯定是天天要干仗的对吧。
  现在我们就有一种新的思维方式,你想轻松怎么办?是不是你只需要告诉别人做什么就可以了。至于怎么个过程,别的就不管了;比如我现在就跟孩子他妈说 一句话给孩子买个西瓜。是不是就O了,对吧。那至于你穿没穿鞋,开没开车,结没结账,我就不管了。最终孩子他妈把西瓜买回来了;然后,叭,往孩子面前一搁:孩儿,吃吧,你妈给你买的。这不是OK了。这种行为方式,在编程里我们称之为:面向对象 的编程语言。
  ​刚刚我们通过 面向过程 完成整个操作用了 7个步骤,那 面向对象 是不是只是把这 7个步骤 变成 一个操作:孩子他妈给孩子买西瓜。完成。是不是就O了,很快速、简单、简洁。现在就是用 一行代码 替换了 七行代码 。作为一个 立志 成为 优秀计算机工程师 的你,会选择用那种方法?毫无疑问,一定是 面向对象 的编程方法了。
  ​那我们再来思考思考:这个 面向对象 我们面对的是谁?或者说这个 对象函数孩子孩子他妈西瓜吃西瓜?再次回到我们的 起点Python一切皆对象。其实对于 面向对象 的编程语言来说 一切都是对象
  举几个例子:“穿鞋” 这个动作是不是就是一个 对象;“电动车” 这个动作是不是就是一个 对象;“” 这个动作是不是就是一个 对象;包括“结账” 这个动作是不是也是一个 对象……那么大家会说:这么多的 对象 有什么好处?我们又怎么把一系列的数据或者行为保存到一个个的 对象 当中。
  比如说:就给 孩子吃瓜 这个事情;我就可以把这个事情保存妈妈 这个 对象 当中,至于她怎么去买,都是由这个 对象内部定义的信息决定 的。对象是什么对象 就是一个 存储数据的容器;它的好处是什么呀?好处就是:我想让孩子吃瓜,我就让孩子他妈去买瓜;我想让孩子吃菜,我就让孩子他妈去买菜……真正的细节就在 对象 里,我不需要再操心了。什么 穿鞋开电动车结账……只要我们把 对象 写好了、完善了,是不是就不需要再担心了。
  再比如说大家应该用过这个爬虫的一个模块:requests;requests.get(‘http://xxxxxxxxxxxx’)。这个 get(’ ') 里面需要传递一个URL地址;此时你愿意传 百度 你就传 百度,你愿意传 新浪 就传一个 新浪,你愿意传一个 小说网站 你就传一个 小说网站……具体细节我不管,我只是把这个对象给你定义好了,你直接用是不是就OK了。其实 这些操作 都是什么?其实,这些操作就是 面向对象 操作。
  那个此时大家心里可能有一个 疑问:这个叫 孩子吃瓜 这件事,里面 妈妈 这个对象中不也得是这么一步一步实现这个步骤吗?这个呢确实没错,但是 区别 在于什么呀?区别在于 是不是这些 步骤 已经存在 于妈妈这个 对象当中 了。我们只要写好这个 对象 是不是OK了,对吧?所以呢,我们来小小的总结一下:

  1) 面向对象 的编程语言,关注 的是 对象,而 不注重 过程,对于 面向对象来说:一切皆对象
  2) 面向对象编程思想,将 所有功能 统一保存对应对象 中,要使用某个功能,直接找到 对应的对象 即可;
  3) 这种 编码方式 比较 容易阅读,并且 易于维护容易复用。但是编写的过程中 不太符合 常规的思维方式刚开始编写的时候相对会比较麻烦

  

2. 类(class)

  我们目前学习的 对象 都是 Python的内置对象,但是 内置对象 并不都能 满足我们的需求,所以我们在开发的过程中经常要 自定义一些对象

   简单理解:它就是相当于一个 图纸这个图纸是干嘛呀?我们以前说 对象 相当于是 一个容器,那么你现在要 创建一个对象,或者你要自己 定义这么一个对象。前面我们说:对象 就像是 容器,那这个这个 容器 的还是 的?这个容器里面是有 一个格两个格 还是 N个格……那这 属性 些都是 由谁决定 的呢?由谁?是不是就是由我们说的这个 图纸 来决定的,对吧。那么你要创建这个 容器,那就得先选择 图纸;这个 图纸 就是我们所说的这个 ;所以 简单的理解 就是一张 图纸,在程序中我们需要根据 创建对象 就是对象的 图纸
  如果上面的这些介绍还没有让你完全明白,那我们来 举个例子:现在呢,我们手上有张 图纸,现在假设,这是一张可以造汽车的图纸;这个时候,我们是不是可以根据这张 图纸,我们造一辆 红色汽车、一辆 蓝色汽车、一辆 黑色汽车……对吧,那么这些车是不是就是 对象红色汽车 一个 对象蓝色汽车 一个 对象黑色汽车 一个 对象、等等等等;那这些对象是从哪来的?是不是根据 图纸 造出来的。所以说我们可以这么理解:我们又称 对象实例(instance)。“ 对象实例 ”这句话我们又怎么理解?我们说这张 图纸 它只是一张 ,它没有什么 实际的形态,但是我们可以 根据原图纸来造出一个车,是不是就相当于把这张 图纸 给他 实例 出来,就是有一个现实中大家可以看的到的东西。
  所以,我们也称:对象实例(instance)。如果 多个对象 是通过 一个类 创建的,我们称 这些对象 是:一类对象。这 一类对象 我们可以用前面的“造汽车”来理解:虽然 颜色 不一样,但 型号 全部都是一样的。再比如说你这个对象是通过“”这个对象创建的,那就是一个 “人类”;假如这个对象是通过“”这个对象创建的,那就是一个 “狗类”……到此呢,类的介绍就已经差不多了;那我们现在再一起回顾一下:我们到现在都学过那些类?int() 、string() 、float() 、bool() 、list() ……那么这些这些都是什么?这些都是 。为什么这么说?来看 参考实例

a = 1
print(a)					# 1

a = int(1)
print(a)					# 1

  实例中,第一个a是什么?是不是一个整数;两个print()的结果都是一样的吧,都是“整数 1”;只是这第二种方法我们平时写的比较少,第二个a的意思是不是:接收数据强制类型转换为整形。
  那我们再来看一下:int() 、string() 、float() 、bool() 、list() ……这些Python语言内置的 有什么特点?是不是他们都是 小写字母开头(括号)结尾 的。所以,当我们需要 自定义类 的时候需要以 大写字母 来开头。当然,这是下一块内容,我们等下再说。
  回到前面,既然我们刚刚说:int()是是一个类;那么a = int(1)这行代码就今天就可以完整的理解:它是创建了一个int()的类的实例。那这个int()的类的实例我们怎么理解?来看下面的 参考实例

def fn_a():
    pass

a = fn_a
print(a,type(a))			# <function fn_a at 0x0000028125B6D160> <class 'function'>

a = int(1)
print(a,type(a))			# 1 <class 'int'>

a = str('Python')
print(a,type(a))			# Python <class 'str'>

  通过观察 参考实例 的运行结果我们可以逐渐清晰:通过 type() 函数 返回对象的类型我们发现 a = int(1) 的对象类型是 class(类)class(类) 的属性是 'int';而 a = fn_a 的对象类型是 function(函数)。虽然它们都很像,但是它们 不是一个东西。同样的 a = str('Python') 的对象类型也是 class(类)class(类) 的属性是 'str'

  说这么多,那读者朋友们一定会问了:我们怎么自己来定义一个 啊?其实,我们自定义一个 就非常简单了;我们自己定义一个类就使用Python语言 内置的关键字 class
  语法实例

# 创建 类 的语法:
class Class_name([父类]):
    pass

  我们本篇文章暂时不讲类 () 里的内容(下一篇),我们先讲一个老生常谈的话题:规范。在这里,我们说当然也就是 类的命名规范。自定义的 的名字要使用大写字母开头;常规的 类 的命名方法我们一般使用 大驼峰命名法

  自定义 语法 以及 相关的注意事项 都已经讲过了,那我们现在就一起来创建我们的第一个类吧。

class MyClass():
    pass

print(MyClass)		# <class '__main__.MyClass'>

  我们已经成功的自己创建了第一个 ,并且通过print(MyClass)打印出的结果得到:<class '__main__.MyClass'>得到的结果是什么意思呢?当前打印的结果是一个 __main__表示当前的 类文件主文件,运行在 主文件 里这个 的名字叫MyClass

  前面说过: 就是 对象图纸。我们现在已经成功的完成一个 的创建了,那我们怎么来创建一个 对象 呢?其实呢,这个操作也是非常的简单。来看 参考实例

class MyClass():
    pass

mc = MyClass()

  这个操作是什么意思呢:我使用MyClass这个 创建了一个对象,这个对象叫做 mcmc就是通过 MyClass这个 创建的 对象mc就是通过 MyClass这个 实例(instance)。我们来通过 函数print() 和 函数type() 一起来看看 mc 打印出来的结果。
  参考实例

class MyClass():
    pass

mc = MyClass()

print(mc,type(mc))		# <__main__.MyClass object at 0x000002698C928400> <class '__main__.MyClass'>

  跳过解释操作,直接翻译结果的意思:首先解释 print(mc) 出来的结果 <__main__.MyClass object at 0x000002698C928400>;我们当前所在的 运行文件主文件,打印的 变量mc MyClass 实例化 后的 对象,存储于 0x000002698C928400 这个内存位置当中。type(mc) 打印的是 变量mc 的类型,意思是 变量mc 是通过MyClass 这个 创建的 对象

  现在我们已经知道 如何创建一个 对象 已经 对象 打印出来的结果,那么如果一个 被多个 对象 实例化 会怎么样呢?
  参考实例

class MyClass():
    pass

mc_1 = MyClass()
mc_2 = MyClass()
mc_3 = MyClass()
mc_4 = MyClass()

  看上面的 参考实例 我们会发现 4个对象 mc_1mc_2mc_3mc_4 其实都属于一个 MyClass() 的实例,它们都是 一类对象;当然了,参考实例 毕竟相对的还是比较简单,我们一眼就能看出来。不过,如果以后我们在真实的开发场景中如何证明 mc_1mc_2mc_3mc_4 4个对象都属于 一类对象 呢?此时,我们来介绍 Python语言 中第一个对 进行操作的 函数 isinstance()
  参考实例

class MyClas():
    pass

class MyClass():
    pass

mc_1 = MyClass()
mc_2 = MyClass()
mc_3 = MyClass()
mc_4 = MyClass()
mc_5 = MyClas()

q = isinstance(mc_1,MyClass)
w = isinstance(mc_2,MyClass)
e = isinstance(mc_3,MyClass)
r = isinstance(mc_4,MyClass)
t = isinstance(mc_5,MyClass
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值