机器学习与深度学习(Python版·微课视频版)
上QQ阅读APP看书,第一时间看更新

1.2 Python语言相关概念

Python是一种面向对象的解释型计算机程序设计语言,具有跨平台(指Linux、macOS以及Windows等操作系统)的特点,其代码可以在不同平台上运行。

为了使初学者更好地理解Python语言,下面讨论几个重要的概念。

1.2.1 程序设计语言

程序设计语言是用于编写计算机程序的语言。计算机程序设计语言的发展,经历了从机器语言、汇编语言到高级语言的历程。

能够调入计算机内存,并由中央处理器(CPU)直接执行的二进制0、1代码组成的指令,称为机器指令。由机器指令写出来的程序就是一串串的0、1代码。不同的CPU具有不同的指令系统,因此用机器语言编写程序时,编程人员需要熟记所用指令系统的全部指令代码和代码的含义,还需要直接对存储空间进行分配。由机器语言写出的程序虽然能够直接执行,运行效率很高,但很难理解、编写效率很低、维护难度很大、入门门槛很高。

由机器语言表述的机器世界与由自然语言(指汉语、英语等人类使用的语言)表述的现实世界之间存在巨大的理解“鸿沟”。程序员的工作就是要把纷繁复杂的现实世界映射到只由0和1组成的机器世界,并利用计算机的快速计算能力来求解现实世界中的问题,这些问题包括科学计算、过程模拟、工业控制和播放动画等。

而程序设计语言就是程序员实现从现实世界到机器世界映射的工具,程序设计语言的发展过程就是不断缩小两个世界之间的“鸿沟”的过程,如图1-16所示。

图1-16 现实世界与机器世界之间的“鸿沟”

在机器语言的基础上首先发展出了汇编语言。汇编语言的指令是机器指令的符号化体现,与机器指令存在着直接的对应关系。汇编语言的指令一般使用有实际含义的英文单词来表示,比如,用JUMP表示无条件转移指令来代替对应的由0和1组成的机器指令。因此,汇编语言更接近表述现实世界的自然语言,缩小了机器世界与现实世界之间的“鸿沟”。

当然,汇编语言编写的程序并不能直接由CPU执行,因此要使用专门的编译软件翻译成机器能够执行的机器语言程序。

汇编语言相比机器语言更容易理解,编写、维护的难度都有所降低。但汇编语言的指令与机器语言的指令一一对应,所以汇编语言学习和使用的难度仍然很大。

高级语言是从汇编语言发展而来的,形式上更接近自然语言的程序设计语言。如在Python里用if…elif…else语句来表示根据条件选择执行路径;相应地,C语言里用if(…){…}else{…}来表示。高级语言的语句不再跟机器指令一一对应,一条语句可以代替几条、几十条甚至几百条汇编指令或机器指令。同样地,高级语言写的程序不能被机器直接执行,需要有相应的编译软件将它翻译成机器语言程序。高级语言这个工具更容易被人们学习和使用,提供了更接近自然语言的表达模式,有效地缩短了现实世界与机器世界之间的“鸿沟”,是目前主要使用的程序设计语言。

1.2.2 面向过程与面向对象程序设计方法

现有的高级程序设计语言可分为两类:面向过程程序设计语言和面向对象程序设计语言。前者包括C和Pascal等,后者包括C++、Java和Python等。

面向过程和面向对象与其说是两种程序设计方法,不如说是面对问题的两种思考模式。

顾名思义,面向过程就是以过程为中心,将问题的求解分解成一系列的过程,每个过程解决一个子问题。程序运行时,从初始过程开始,层层推进,直至解决最终问题。面向过程主要关注功能,每个过程具备一个解决某子问题的功能。以简化的图书馆信息处理系统为例,在借书的信息处理过程中,问题的求解分解为输入书名、存书数量是否大于0、登记读者编号和时间、存书数量减1、告知读者已借完等过程,如图1-17所示。每个过程可用一段子程序来实现,如Python的函数。

图1-17 面向过程程序设计方法示例

面向对象是以对象为中心,它先把问题的参与方抽象为一个一个的对象。对象有属性和行为,属性可以表示对象的特征和状态,行为表示对象的功能。如图书馆信息处理系统中,参与借书与还书的读者、管理员和书,可以分别抽象为三类对象,如图1-18所示。读者对象有编号、姓名属性,有借书和还书行为。管理员对象有借书管理和还书管理行为。书对象有书名、存书数量、借阅读者编号属性,有查询库存数量、出库、入库行为。在问题域中,读者对象和书对象可能有很多个,分别代表多个读者和多本书,而管理员对象可能只有一个。

图1-18 抽象为对象的示例

在建立好对象之后,解决问题的基本方式就是让这些对象相互驱动、相互作用,使每个对象按照设计的目标改变其属性状态。上例中,在借书时,由读者对象驱动管理员对象开始借书管理行为,管理员的借书管理行为又驱动书对象的出库行为,书对象的出库行为又驱动自身的查询库存数量行为,如果存书数量足够,则改变书对象存书数量属性……显然,面向对象思考问题的方式更接近于现实世界的方式。

这两种程序设计方法没有好坏之分,它们各自适用于不同的场合。面向对象方法的程序要事先抽象出代表对象的类,涉及抽象、封装、可重用等概念,比面向过程方法的入门门槛要高得多。但是面向对象的程序可扩展性高,当需要增加功能时,只需要增加对象的属性和行为即可,如上例中,可以给管理员对象增加一个盘点行为,由该行为驱动所有书对象的查询库存数量行为,从而实现查询所有书的库存数量的功能。而面向过程的程序要增加功能,相应的工作一般要复杂得多。

Python是一门面向对象的程序设计语言,但并不要求机器学习的初学者要全部掌握面向对象程序设计的方方面面。像sklearn等扩展库提供了以对象的方式封装的机器学习算法,对初学者来说,只需要掌握其使用方法即可,将在下文结合示例介绍。

1.2.3 平台无关性和解释型语言

如前所述,高级程序设计语言编写的程序需要翻译成机器指令才能运行。翻译得到的机器指令一般要作为文件保存在硬盘上,在需要的时候由操作系统调入内存执行,这样的文件称为可执行文件。可执行文件在Windows操作系统中一般是EXE和COM等格式,在Linux操作系统中一般是ELF格式,在macOS操作系统中一般是Mach-O格式,它们不能互用。这种直接翻译成机器指令的语言称为编译型语言,如C和C++等。

不同操作系统的运行机制不同,因此基于不同操作系统的编程思路和方式有一定的差别。在不同平台(操作系统也习惯性称为平台)上完成相同功能的程序时,从源代码到可执行文件都有不少的差异,这就导致了同样功能的程序需要在不同的平台上重新编写或者适当修改才能实现跨平台应用。

为了减少程序员的工作量,提升开发速度,使程序员只需要编写一次代码即可实现跨平台应用,人们采用分层的思路来实现平台无关性。Python就是实现了平台无关性的高级程序设计语言,其他影响力大的跨平台语言还有Java,二者实现平台无关性的方法基本相似。它们是在源代码程序与各平台的机器码之间插入了一个虚拟机,也就是说源代码程序不再直接翻译成机器码,而是先编译成虚拟机的字节码,再将字节码解释成各平台可执行的机器码,如图1-19所示。

图1-19 平台无关性与解释型语言

此时,程序设计者不再直接面对Windows、Linux以及macOS等有差异的具体操作系统,而是面对一个完全一样的虚拟机。这个虚拟机里有各种该有的资源,如CPU、内存、显示设备、打印设备等。程序设计者操作和使用的是虚拟机里的这些虚拟资源。

字节码可以看作是虚拟机的机器码。Python语言写出来的源代码要先通过编译器编译成字节码,在运行时再解释成目标平台的机器码,才能被执行。不同的平台都有相应的官方发布的解释器,它们负责将字节码解释成本平台能够运行的机器码。解释器实际上起到了将虚拟机映射到具体平台的作用。

Python源代码程序是以.py为扩展名的文本文件,经过编译后得到的字节码文件是以.pyc为扩展名的文件。

当然,解释型语言在获得平台无关性等好处的同时,也会有执行效率降低等不利之处。