一切皆对象

面向过程与面向对象

最早接触 这个概念是初学Java的时候,当初对这个概念不是很能理解。为此在实验室上课的时候还向远程教学的老师请教,老师解释了半天,我还是不能理解(很尴尬),最后还是身边的学长在我们聊天室里发了一张妹纸图片,图片上写着对象,才结束了当时尴尬的局面。如今想来也是很有趣,的确那张图片上的妹纸就是一个活生生的 ,只不过当时对这种这种 的思想理解地不是很深刻,无法准确地把握住其中精妙的思想。也因为当时由于先前学习的是C语言这门 的语言,面向过程的编程思想,我觉得 。但面向对象编程不同, 。

当时年少无知的我,由于代码没写过几行,更没有如工程师一样有过开发大型软件的体验,很难体会到如C语言这样的面向过程的编程语言,在实际开发大型软件中有多么困难,后期的软件维护更是件反人类的事情。所以一直觉得面向过程挺好的呀,代码简洁,效率又高。这也的确是面向过程语言的优势,甚至还有大神们专门提倡大家使用面向过程语言开发,好比Linux内核最早的开发者林纳斯·托瓦兹(Linux内核而不是Linux发行版,Linux发行版是各个组织、厂商根据用户的需求将Linux系统与各种应用软件集成发行的,而且这里讲林纳斯是Linux内核最早开发者,那是因为后来的Linux内核不仅仅只是他一个人写的,是一个内核小组维护的),他的在Linux方面的建议从来都是能用C语言就不要用C++,他认为C语言效率非常好,C++语言一部分的面向对象设计妨碍了它的性能,并且是强烈不建议这样做。

但并不是所有的软件开发者都是林纳斯那样的天才,而且面向过程语言的出现可以说就是对早期汇编语言的一种抽象。众所周知,汇编语言这东西完全就是对最底层的 机器语言指令集的简单抽象而已,所以说汇编语言的思路就是按照机器指令执行的步骤来的。而面向过程的语言,好比C语言,在很大程度上的编程思想也是在学会如何使用计算机执行的步骤来完成特定的任务(所以我觉得像解数学题一样,一步一步的)。所以早期的面向过程编程思想的出现,完全是为了让人去适应计算机的思维来解决问题。

然而不幸的是,一旦要处理的问题很大了,人类就很难像计算机一样把握住问题的每个细节,这会陷入思维困境。这时人类思维就显得很高明,人类思维处理问题注重问题本身的抽象,而选择忽略具体的细节。

以前看过这样一个故事,从前有个农夫想砍树,然后他想呀砍树需要斧头,他又想斧头需要用铁去锻造,铁块需要铁矿石提炼,铁矿石需要去开采,开采需要铁锹工具……最后他发现砍树太复杂太麻烦了,最后不了了之。

计算机的思维或者说面向过程编程思想,就有点像故事中的农夫一样,解决一个问题需要将问题整个具体细节都描述出来。只不过,具体细节太多,人类思维往往就令人抓不住问题的关键了。

面向对象编程思想来解决这个砍树的问题便是:农夫(对象)需要一把斧头(属性),然后找到一棵树(对象),接着砍树(方法)。这就是砍树这个问题的核心,两个对象之间的交互(农夫和数),然后调用一些属性(斧头)、方法(砍树),就解决了整个问题。

有人会问那些 “斧头”、“砍树” 哪来的,答案是:提前好的,只需要调用就行了。问题的核心是如何 “砍树” ,而不是问这些东西的具体细节。这才是人类思维解决问题的特点: 。

计算机科学家就是这样在面向过程编程语言开发大型项目的失败后,提出了这种更符合人类思维的编程思想——面向对象编程。面向对象编程语言的出现,为开发大型软件提供了解决的方法。但这并不能说明面向对象编程就比面向过程编程更好,两者应该是互补关系,而不是孰强孰弱。就像一位计算机大师曾说过的一样

我认为,面向对象的目标从来都不是复用和扩展,而是提供一种处理复杂问题的方法。

面向对象语言出现地比面向过程语言更晚,也是顺应历史发展潮流的。早期的计算机硬件性能不强,为了使软件程序功能强大,那些程序员编写的程序恨不得榨干计算机中每一寸硬件性能。在Linux内核的早期开发中,为了追求性能,有一些部分甚至是用汇编语言编写的。同样的程序,使用面向过程语言编写比使用面向对象语言编写,占用的硬件资源更少,效率更高。如今,在操作系统级等偏底层的开发(好比PC操作系统、路由器系统、各种智能家居等等),性能要求依然很高,所以依旧用的是C、C++这种面向过程的编程语言,原因无它,天下武功唯快不破!而面向对象语言Java、Python等真正施展才华的地方是大型软件开发,在软件复杂性与软件性能权衡中,软件性能显得不是很重要。(因为还有很多其他地方会消耗时间,性能瓶颈一般不会卡在这,好比有时候网络传输速度影响比软件运行速度影响更大)

纯面向对象的Python

在Java圣经《Thinking in java》书中有一章标题就是。虽然Java作为一门纯面向对象语言,相对于C++语言的设计的确很符合 这句话的描述。但是Java中并非所有的设计都是纯面向对象的,在最初的设计中为了提高程序的效率,Java的9种基本数据类型(boolean、char、byte、short、int、long、float、double、void)的底层实现原理与对象是不同的。(当然了,后来为了解决这个问题,设计了包装器类型来为基本数据类型实现属性与方法的添加)

而Python,从一开始的设计就遵循着 的设计理念。在使用Python的过程中,可以感受到Python一切皆对象的强大之处,甚至连数据类型本身也是一种对象!程序中很多在C语言中所称之为的 ,其实只是对象的引用,而非对象本身,这一点非常重要!

对象与变量区别

数据类型本身也是一种对象

对象是确定的,变量是不确定的

“对象是确定的” 并不是说 “对象是不变” 的,而是指对象被创建的那一刻在内存中的地址也就确定了。因为Python中有一些对象是 ,即对象的值可以发生改变,好比: 和 。

“变量是不确定的” 也并不是说 “变量背后引用的对象是不确定的”,而是指 “当前变量引用的对象不一定就是上一次变量所指的对象了”。

下面先讨论一下 的特点

内置函数名其实也是一个变量,引用的是函数对象

对于 有点特殊,因为这涉及到Python当中 的问题。下面简单谈论一下,有关深复制与浅复制的特性留作下次。

比较两个对象相同

:比较两个变量背后引用的对象的值是否相等

: 比较两个变量背后引用的对象所有信息(包括对象的值、对象的内存地址)是否相等

上面讲到Python中对象与变量的区别,但有时候遇到下面代码这种问题,意味着遇到了Python 3缓冲机制问题,所以才会出现这样的情况

缓冲机制之外,值相等的对象只有 运算才会为 , 运算为

缓冲机制之外的小数字的情况

缓冲机制之外的字符串的情况

对于可变对象的比较而言,符合规律,不存在特殊

总结

总而言之,好好体会Python中一切皆对象的概念,在编写代码的时候会有更多的灵活性,能够充分地利用好Python这门动态语言带来的好处。不过,一定要理解深刻。这篇文章写的总结,也仅仅是我目前所了解到的,也许还有许多认识不足之处。如有错误,请多指教!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180817G20AQU00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券