从Python开始学编程(txt+pdf+epub+mobi电子书下载)


发布时间:2020-07-08 23:37:33

点击下载

作者:Vamei

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

从Python开始学编程

从Python开始学编程试读:

前言

从读博士起,我对编程的兴趣忽然浓厚起来。当时做大规模并行运算,需要自己写很多程序和脚本。作为新进研究组的新人,我自觉负担起很多写程序的活儿。写得多了,兴趣也变得浓厚。

那个时候抓紧一切机会学习编程。在我读博的研究所里,有一位英国教授也喜欢编程。她叫爱玛·希尔(Emma Hill),教我们用编程语言处理地球科学的数据。有一天,我路过她的办公室。她问我最近的学习进度。“准备学Perl呢,”我回答说,“感觉Perl在地理领域应用很广。”“你为什么不学学Python呢?”爱玛问我,“这门语言发展很快。你学会了或许可以教教我。”

我之前听过Python的一些传闻,比如那句著名的“人生苦短,我用Python”。但我担心Python在地球科学研究方面不如Perl积累深厚。有了爱玛的鼓励,我下定决心去研究Python。Python学起来确实很快。没过多久,我就可以用Python来解决我在科研中遇到的大部分问题了。记忆比较深刻的是,有一次下载来自美国研究所的一批气象数据。我用Python中的多线程并发下载,创造了大学中网络传输的纪录。学习加实践,让我爱上了这门语言。

随后,我开始写一系列博客,记录自己学习Python的过程。这一系列的文章叫“Python快速教程”。我想在这些文章中呈现出Python简单易学的特点,以便让更多的人也来享受编程的乐趣。在写作过程中我意识到,要想讲明白一门编程语言,还要引入额外的背景知识。我的编程博客也从Python开始,拓展到网络协议、操作系统、算法、数据分析等方面。写的时间越长,收获的读者也越来越多。每当有人告诉我看着我的文章学会编程时,我总会感到惊喜。因此,我非常感谢爱玛给我推开的这扇门。

完成博士学业之后,我需要在科研和编程之间选择。由于编程带给我的美好体验,我毫不犹豫地选择了编程。将近三十岁的我,和二十出头的年轻人一起做产品、调试、debug。我必须要非常努力,才能赶上这群富有天赋而精力旺盛的年轻人。但我并不觉得辛苦。辛苦是学习的台阶。在编程中,我享受着脑细胞的疯狂激活,享受着未知错误的折磨,以及苦苦思索之后的豁然开朗。更棒的是,我的伙伴总是以乐观的态度来看待技术,以享受的心态来享受编程。我从中受益良多。更何况,计算机浪潮已经并将继续改变世界。我很幸运,能加入浪潮中。“Python快速教程”得到了不少编辑的认可。他们希望我能把博客文章改编成一本书。写书当然是莫大的荣幸,我很感谢每一位编辑的赏识。可在博士学业的压力下,我能抽出的时间实在有限。终于拖到博士毕业,我才开始认真整理之前的文章。把略显凌乱的博客文章改编成书,工作量比我想象的要大得多。在此期间,我也开始了一个新的项目,研发一款用于畜牧的智能芯片。生活的节奏又变得忙碌,能分给写书的时间大大减少。结果,从签合约到完稿,我花了超过半年的时间。幸好编辑安娜对我的拖延症格外包容。

这本书的最终诞生,有赖于许多人的支持。感谢父母对我的激励和教育,感谢妻子一直以来的陪伴。雷雨田绘制的精美插画,让枯燥的技术书变得生动有趣。在写作博客的过程中,许多读者都指正过文章中的错误,或者对写作方向提出建议。在成书过程中,王豪、周昕梓和黄杜立对文章进行审阅校正。正是因为他们的审阅校正,我才能放心地交稿。此外还有很多帮助过我的人,不能一一列举,只好一并表达感激。

在我现在的工作中,Python依然占据着重要的地位。我会用Python进行网站开发和大数据分析,还会用Python来写一些在单片机上运行的脚本。当然,我也离不开其他语言,比如处理数据库的SQL、编写安卓App的Java、开发网页前端的JavaScript等。但Python让我爱上编程。我也希望,这本书能让读者也爱上Python,并且继续像我的博客文章一样,能帮助到那些想学习编程的人。在此存一个美好心愿。Vamei第1章用编程改造世界1.1 从计算机到编程1.2 所谓的编程,是做什么的1.3 为什么学Python1.4 最简单的Hello World附录A Python的安装与运行附录B virtualenv

本章将简要介绍计算机和编程的历史。从计算机出现以来,硬件性能得到飞跃式的发展。与此同时,编程语言也几经变迁,产生了多种编程范式。Python语言以简洁灵活的特点,在诸多编程语言中打下一片天地。通过历史,我们不但能体验Python的特色,还能了解这门语言想要解决的痛点。本章将以一个简单的“Hello World!”程序结束,从此开启Python之旅。1.1 从计算机到编程

人能运算和记忆,但更了不起的是善于借用工具。人类很早就开始利用方法和工具,辅助计算和记忆这样高度复杂的认知活动。古人用给绳子打结的方式来记录圈养的牛羊,我们的祖先很早就能以眼花缭乱的速度使用算盘。随着近代工业化的发展,社会对计算的需求越来越强烈。收税需要计算,造机器需要计算,开挖运河也需要计算。新的计算工具不断出现。利用对数原理,人们制造出计算尺。计算尺可以平行移动尺子来计算乘除法。19世纪的英国人巴贝奇设计了一台机器,用齿轮的组合来进行高精度的计算,隐隐预示着机器计算的到来。20世纪初有了机电式的计算机器。电动马达驱动变档齿轮“咯吱”转动,直到得到计算结果。

二战期间,战争刺激了社会的计算需求。武器设计需要计算,比如坦克的设计、潜艇的外形、弹道的轨迹。社会的军事化管理需要计算,比如火车调度、资源调配、人口动员。至于导弹和核弹这样的高科技项目,更需要海量的计算。美国研制原子弹的曼哈顿计划,除了使用IBM的计算机器外,还雇佣了许多女孩子进行手工运算。计算本身甚至可以成为武器。电影《模仿游戏》就讲述了英国数学家阿兰·图灵(Alan Mathison Turing)破解德国传奇密码机的故事。图灵的主要工具,就是机电式的计算机器。值得一提的是,正是这位图灵,提出了通用计算机的理论概念,为未来的计算机发展做好了理论准备。现在,计算机学科的最高奖项就以图灵命名,以纪念他的伟大贡献。德国工程师康拉德·楚泽(Konrad Zuse)发明的Z3计算机能编写程序。这看起来已经是一台现代计算机的雏形了。

计算工具的发展是渐进的。不过历史把第一台计算机的桂冠颁给了战后宾夕法尼亚大学研制的埃尼阿克(ENIAC,Electronic Numerical Integrator And Computer)。埃尼阿克借鉴了前任的经验,远非横空出世的奇迹。但它最重要的意义,是向人们展示了高速运算的可能性。首先它是一台符合图灵标准的通用计算机,能通过编程来执行多样的计算任务。其次,与机电式计算机器不同,埃尼阿克大量使用真空管,从而能快速运算。埃尼阿克的计算速度比之前的机电型机器提高了一千倍,这是一次革命性的飞跃。因此,即便计算辅助工具同样历史悠久,但人们仍认为埃尼阿克引领了一个新的时代—计算机时代。

从埃尼阿克开始,计算机经历了迅猛的发展。计算机所采用的主要元件,从真空管变成大规模集成电路。计算机的运算性能,每一两年的时间就会翻倍。但计算机的大体结构,都采用了冯·诺依曼体系。这一体系是长期演化的结果,但冯·诺依曼进行了很好的总结。按照冯·诺依曼的设计,计算机采用二进制运算,包括控制器、运算器、存储器、输入设备和输出设备五个部分,如图1-1所示。五个部分相互配合,执行特定的操作,即指令。这五个部分各有分工。图1-1 冯·诺依曼结构1. 控制器:计算机的指挥部,管理计算机其他部分的工作,决定执

行指令的顺序,控制不同部件之间的数据交流。2. 运算器:顾名思义,这是计算机中进行运算的部件。除加减乘除

之类的算数运算外,还能进行与、或、非之类的逻辑运算。运算

器与控制器一起构成了中央处理器(CPU,Central Processing

Unit)。3. 存储器:存储信息的部件。冯·诺依曼根据自己在曼哈顿工程中

的经验,提出了存储器不但要记录数据,还要记录所要执行的程

序。4. 输入设备:向计算机输入信息的设备,如键盘、鼠标、摄像头等。5. 输出设备:计算机向外输出信息的设备,如显示屏、打印机、音

响等。

人们最常想到的计算机是台式机和笔记本电脑。其实,计算机还存在于智能手机、汽车、家电等多种设备中。但无论外形如何多变,这些计算机都沿袭了冯·诺依曼结构。不过在具体细节上,计算机之间又有很大的差别。有的计算机使用了多级缓存,有的计算机只有键盘没有鼠标,有的计算机用磁带存储。计算机的硬件是一门很庞杂的学问。幸运的是,计算机用户大多不需要和硬件直接打交道。这一点是操作系统(Operating System)的功劳。

操作系统是运行在计算机上的一套软件,负责管理计算机的软硬件资源。有的时候我们请人修电脑,他可能会说“电脑需要重装一下”。这个“重装”,就是重新安装操作系统的意思。无论是微软的Windows,还是苹果的iOS,都属于操作系统。我们编程时,大多数时候都是通过操作系统这个“中间商”来和硬件打交道的。操作系统提供了一套系统调用(System Call),如图1-2所示,规定了操作系统支持哪些操作。当调用某个系统调用时,计算机会执行对应的操作。这就像是按下钢琴上的一个键,钢琴就会发出对应的音律一样。系统调用提供的功能非常基础,有时调用起来很麻烦。操作系统因此定义一些库函数(Library Routine),将系统调用组合成特定的功能,如同几个音律组成的和弦。所谓的编程,就是用这些音律和和弦,来组成一首美妙的音乐。图1-2 硬件、操作系统和应用程序的关系1.2 所谓的编程,是做什么的

编程中总是在调用计算机的基本指令。如果完全用基础指令来说明所有的操作,代码将超乎想象的冗长。IBM前总裁小沃森的自传中就提到,他看到一位工程师想要做乘法运算,输入程序用的打孔卡叠起来有1.2米高。幸好,程序员渐渐发现,许多特定的指令组合会重复出现。如果能在程序中复用这些代码,则可以节省很多工作量。复用代码的关键是封装(Packaging),即把执行特殊功能的指令打包成一个程序块,然后给这个程序块起个容易查询的名字。如果需要重复使用这个程序块,则可以简单地通过名字调用。就好像食客在点菜时,只需告诉厨师做“鱼香肉丝”,而不需要具体说明要多少肉、多少调料、烹制多久一样。刚才提到的操作系统,就是将一些底层的硬件操作组合封装起来,供上层的应用程序调用。当然,封装是有代价的,它会消耗计算机资源。如果使用的是早期的计算机的话,封装和调用的过程会非常耗时,最终得不偿失。

封装代码的方式也有很多种。根据不同的方式,程序员写程序时要遵循特定的编程风格,如面向过程编程、面向对象编程和函数式编程。用更严格的术语来说,每种编程风格都是一种编程范式(Programming Paradigm)。编程语言开始根据编程范式区分出阵营,面向过程的C语言、面向对象的Java语言、面向函数的Lisp语言等。任何一种编程范式编写出来的程序,最终都会翻译成上面所述的简单功能组合。所以编程的需求总是可以通过多种编程范式来分别实现,区别只在于这个范式的方便程度而已。由于不同的范式各有利弊,所以现代不少编程语言都支持多种编程范式,以便程序员在使用时取舍。Python就是一门多范式语言。某一范式的代表性语言,也开始在新版本中支持其他范式。原本属于面向对象范式的Java语言,就在新版本中也开始加入函数式编程的特征。

编程范式是学习编程的一大拦路虎。对于一个程序员来说,如果他熟悉了某一种编程范式,那么他就能很容易地上手同一范式的其他编程语言。对于一个新手来说,一头扎进Python这样的多范式语言,会发现同一功能有不同的实现风格,不免会感到困惑。一些大学的计算机专业课程,选择了分别讲授代表性的范式语言,比如C、Java、Lisp,以便学生在未来学习其他语言时有一个好的基础。但这样的做法,会将学习过程拉得很漫长。在我看来,Python这样的多范式语言提供了一个对比学习多种编程范式的机会。在同一语言框架下,如果程序员能清晰地区分出不同的编程范式,并了解各自的利弊,将起到事半功倍的效果。这也是本书中想要做到的,从面向过程、面向对象、函数式三种主流范式出发,在一本书的篇幅内学三遍Python。这样的话,读者将不止是学会了一门Python语言,还能为未来学习其他语言打好基础。

学习了包括Python在内的任何一门编程语言后,就打开了计算机世界的大门。通过编程,你几乎可以发挥出计算机所有的功能,给创造力提供了广阔的施展空间。想到某个需求,比如统计金庸小说中的词频,自己就能写程序解决。有了不错的想法,例如想建立一个互助学习的网站,也可以立即打开电脑动手编写。一旦学会了编程,你会发现,软件主要比拼的就是大脑和时间,其他方面的成本都极为低廉。编写出的程序还会有许多回报。可以是经济性的回报,比如获得高工资,比如创立一家上市的互联网企业。也可以是声誉性的回报,比如做出了很多人喜爱的编程软件,比如攻克了困扰编程社区的难题等。正如《黑客与画家》一书中所说,程序员是和画家一样的创作者。无穷的创造机会,正是编程的一大魅力所在。

编程是人与机器互动的基本方式。人们通过编程来操纵机器。从18世纪的工业革命开始,人们逐渐摆脱了手工业的生产方式,开始转向机器生产。机器最开始用于棉纺工业,一开始纺出的纱线质量比不上手工纺制的。但机器可以昼夜工作,不知疲倦,产量也是惊人。因此,到了18世纪末,全球大部分的棉布都变成了机器生产。如今,机器在生活中已经屡见不鲜。人工智能这样的“软性机器”,也越来越多地进入生产和生活。工人用机器来制造手机、医生操纵机器来进行微创手术、交易员用机器进行高频的股票交易。残酷一点讲,对机器的调配和占有能力,将会取代血统和教育,成为未来阶级区分的衡量标准。这也是编程教育变得越来越重要的原因。

机器世界的变化,正在改变世界的工作格局。重复性工作消亡,程序员的需求量却在不断加大。很多人都在自学编程,以便跟上潮流。幸好,编程也变得越来越简单。从汇编语言,到C语言,再到Python语言,编程语言越来越亲民。以Python为例,在丰富的模块支持下,一个功能的实现只需要寥寥几个接口的调用,不需要费太多工夫。我们之前所说的封装,也是把功能给打包成规范的接口,让别人用起来觉得简单。编程用精准的机器为大众提供了一个规范化的使用接口,无论这个接口是快速安全的支付平台,还是一个简单快捷的订票网站。这种封装和接口的思维反映在社会生活的很多方面。因此,学习编程也是理解当代生活的一个必要步骤。1.3 为什么学Python

正如1.2节所说,高级语言的关键是封装,让程序编写变得简单。Python正是因为在这一点上做得优秀,才成为主流编程语言之一。Python的使用相当广泛,是Google的第三大开发语言,也是Dropbox、Quora、Pinterest、豆瓣等网站主要使用的语言。在很多科研领域,如数学、人工智能、生物信息、天体物理等,Python都应用广泛,渐有一统天下的势头。当然,Python的成功并非一蹴而就。它从诞生开始,已经经历了二三十年的发展。回顾Python的历史,我们不但可以了解Python的发展历程,还能理解Python的哲学和理念。

Python的作者是吉多·范·罗苏姆(Guido von Rossum)。罗苏姆是荷兰人。1982年,他从阿姆斯特丹大学(University of Amsterdam)获得了数学和计算机硕士学位。然而,尽管他算得上是一位数学家,但他更加享受计算机带来的乐趣。用他的话说,尽管拥有数学和计算机双料资质,但他总是趋向于做计算机相关的工作,并热衷于做任何和编程相关的活儿。

在编写Python之前,罗苏姆接触并使用过诸如Pascal、C、Fortran等语言。这些语言的关注点是让程序更快运行。在20世纪80年代,虽然IBM和苹果已经掀起了个人电脑浪潮,但这些个人电脑的配置在今天看来十分低下。早期的苹果电脑只有8MHz的CPU主频和128KB的内存,稍微复杂一点的运算就能让电脑死机。因此,当时编程的核心是优化,让程序能够在有限的硬件性能下顺利运行。为了增进效率,程序员不得不像计算机一样思考,以便能写出更符合机器口味的程序。他们恨不得用手榨取计算机的每一寸能力。有人甚至认为C语言的指针是在浪费内存。至于我们现在编程经常使用的高级特征,如动态类型、内存自动管理、面向对象等,在那个时代只会让电脑陷入瘫痪。

然而,以性能为唯一关注点的编程方式让罗苏姆感到苦恼。即使他在脑子中清楚知道如何用C语言来实现一个功能,但整个编写过程仍然需要耗费大量的时间。相对于C语言,罗苏姆更喜欢Shell实现功能的方式。UNIX系统的管理员们常常用Shell去写一些简单的脚本,以进行一些系统维护的工作,比如定期备份、文件系统管理,等等。Shell可以像胶水一样,将UNIX下的许多功能连接在一起。许多C语言下数百行的程序,在Shell下只用几行就可以完成。然而,Shell的本质是调用命令,它并不是一个真正的语言。比如说,Shell数据类型单一、运算复杂等。总之,Shell不是一个合格的通用程序语言。

罗苏姆希望有一种通用程序语言,既能像C语言那样调用计算机所有的功能接口,又能像Shell那样轻松地编程。最早让罗苏姆看到希望的是ABC语言。ABC语言是由荷兰的数学和计算机研究所(Centrum Wiskunde & Informatica)开发的。这家研究所是罗苏姆上班的地方,因此罗苏姆正好能参与ABC语言的开发。ABC语言以教学为目的。与当时的大部分语言不同,ABC语言的目标是“让用户感觉更好”。ABC语言希望让语言变得容易阅读、容易使用、容易记忆和容易学习,以此来激发人们学习编程的兴趣。比如,下面是一段来自维基百科的ABC程序,这个程序用于统计文本中出现的词的总数:HOW TO RETURN words document: PUT {} IN collection FOR line IN document: FOR word IN split line: IF word not.in collection: INSERT word IN collection RETURN collection

HOW TO用于定义一个函数,ABC语言使用冒号和缩进来表示程

(1)序块,行尾没有分号,for和if结构中没有括号。上面的程序读起来就像一段自然的文字。

尽管已经具备了良好的可读性和易用性,但ABC语言并未流行起来。在当时,ABC语言编译器需要比较高配置的电脑才能运行。在那个时代,高配置电脑是稀罕物,其使用者往往精通计算机。这些人更在意程序的效率,而非语言的学习难度。除了性能,ABC语言的设计还存在一些致命的问题:● 可拓展性差。ABC语言不是模块化语言。如果想在ABC语言中增

加功能,比如对图形化的支持,就必须改动很多地方。● 不能直接进行输入输出。ABC语言不能直接操纵文件系统。尽管

你可以通过诸如文本流的方式导入数据,但ABC语言无法直接读

写文件。输入输出的困难对于计算机语言来说是致命的。你能想

像一个打不开车门的跑车么?● 过度革新。ABC语言用自然语言的方式来表达程序的含义,比如

上面程序中的HOW TO(如何)。然而对于掌握了多种语言的程

序员来说,他们更习惯用function或者define来定义一个函数。同

样,程序员也习惯了用等号(=)来分配变量。革新尽管让ABC

语言显得特别,但实际上增加了程序员的学习难度。● 传播困难。ABC编译器很大,必须被保存在磁带(tape)上。罗

苏姆在学术交流时,就必须用一个大磁带来给别人安装ABC编译

器。这使得ABC语言很难快速传播。

1989年,为了打发圣诞节假期,罗苏姆开始写Python语言的编译/解释器。Python这个词在英文中的意思是蟒蛇。但罗苏姆选择这(2)个名字的原因与蟒蛇无关,而是来源于他挚爱的一部电视剧。他希望这个新的叫作Python的语言,能实现他的理念。也就是一种在C和Shell之间,功能全面、易学易用、可拓展的语言。罗苏姆作为一名语言设计爱好者,已经有过设计语言的的尝试。虽然上次的语言设计并不成功,但罗苏姆依然乐在其中。这一次设计Python语言,也不过是他又一次寻找乐趣的小创造。

1991年,第一个Python编译/解释器诞生。它是用C语言实现(3)的,能够调用C语言生成的动态链接库。从一出生,Python就已经具有了一直保持到现在的基本语法:类(class)、函数(function)、异常处理(exception)、包括表(list)和词典(dictionary)在内的核心数据类型,以及模块(module)为基础的拓展系统。图1-3 最初的Python图标

Python语法很多来自C,但又受到ABC语言的强烈影响。Python像ABC语言一样,比如用缩进代替花括号,从而保证程序更易读(readability)。罗苏姆认为,程序员读代码的时间要远远多于写代码的时间。强制缩进能让代码更清晰易读,应该予以保留。但与ABC语言不同的是,罗苏姆同样重视实用性(practicality)。在保证易读性的前提下,Python会乖巧地服从其他语言中已有的一些语法惯例。Python用等号赋值,与多数语言保持一致。它使用def来定义函数,而不是像ABC语言那样使用生僻的HOWTO。罗苏姆认为,如果是“常识”上已确立的东西,就没有必要过度创新。

Python还特别在意可拓展性(extensibility),这是罗苏姆实用主义原则的又一体现。Python可以在多个层次上拓展。从高层上,你可以引入其他人编写的Python文件,来为自己的代码拓展功能。如果出于性能考虑,你还可以直接引入C和C++语言编译出的库。由于C和C++语言在代码方面的多年储备,Python相当于站在了巨人的肩膀上。Python就像是使用钢构建房一样,先规定好大的框架,再借着模块系统给程序员以自由发挥的空间。

最初的Python完全由罗苏姆本人开发。由于Python隐藏了许多机器层面上的细节,并凸显出了逻辑层面的编程思考,所以这个好用的语言得到了罗苏姆同事的欢迎。同事们在工作中乐于使用Python,然后向罗苏姆反馈使用意见,其中不少人都参与到语言的改进。罗苏姆和他的同事构成了Python的核心团队,他们将自己大部分的业余时间都奉献给了Python。Python也逐渐从罗苏姆的同事圈传播到其他科研机构,慢慢用于学术圈之外的程序开发。

Python的流行与计算机性能的大幅提高密不可分。20世纪90年代初,个人计算机开始进入普通家庭。英特尔发布了486处理器,成为第四代处理器的代表。1993年,英特尔又推出了性能更好的奔腾处理器。计算机的性能大大提高。程序员不必再费尽心力提高程序效率,开始越来越关注计算机的易用性。微软发布Windows 3.0开始的一系列视窗系统,用方便的图形化界面吸引了大批普通用户。那些能快速生产出软件的语言成为新的明星,比如运行在虚拟机上的Java。Java完全基于面向对象的编程范式,能在牺牲性能的代价下,提高程序的产量。Python的步伐落后于Java,但它的易用性同样符合时代潮流。前面说过,ABC语言失败的一个重要原因是硬件的性能限制。从这方面来说,Python要比ABC语言幸运许多。

另一个悄然发生的改变是互联网。20世纪90年代还是个人电脑的时代,微软和英特尔挟PC以令天下,几乎垄断了个人电脑市场。当时,大众化的信息革命尚未到来,但对于近水楼台的程序员来说,互联网已经是平日里常用的工具。程序员率先使用互联网进行交流,如电子邮件和新闻组。互联网让信息交流成本大大降低,也让有共同爱好的人能够跨越地理限制聚合起来。以互联网的通信能力为基础,开源(Open Source)的软件开发模式变得流行。程序员利用业余时间进行软件开发,并开放源代码。1991年,林纳斯·托瓦兹在comp.os.minix新闻组上发布了Linux内核源代码,吸引了大批程序员加入开发工作,引领了开源运动的潮流。Linux和GNU相互合作,最终构成了一个充满活力的开源平台。

罗苏姆本人也是一位开源先锋,他维护了一个邮件列表,并把早期的Python用户都放在里面。早期Python用户就可以通过邮件进行群组交流。这些用户大多都是程序员,有相当优秀的开发能力。他们来自许多领域,有不同的背景,对Python也提出了各种各样的功能需求。由于Python相当开放,又容易拓展,所以当一个人不满足于现有功能时,他很容易对Python进行拓展或改造。随后,这些用户将改动发给(4)罗苏姆,由他决定是否将新的特征加入到Python中。如果代码能被采纳,将会是极大的荣誉。罗苏姆本人的角色越来越偏重于框架的制定。如果问题太复杂,则罗苏姆会选择绕过去,也就是走捷径(cut (5)the corner),把其留给社区的其他人解决。就连创建网站、筹集基(6)金这样的事情,也有人乐于处理。社区日渐成熟,开发工作被整个社区分担。

Python的一个理念是自带电池(Battery Included)。也就是说,Python已经有了功能丰富的模块。所谓模块,就是别人已经编写好的Python程序,能实现一定的功能。一个程序员在编程时不需要重复造轮子,只需引用已有的模块即可。这些模块既包括Python自带的标准库,也包括了标准库之外的第三方库。这些“电池”同样是整个社区的贡献。Python的开发者来自于不同领域,他们将不同领域的优点带给Python。Python标准库中的正则表达(regular expression)参考了Perl,函数式编程的相关语法则参考了Lisp语言,两者都来自于社区的贡献。Python在简明的语法框架下,提供了丰富的武器库。无论是建立一个网站,制作一个人工智能程序,还是操纵一个可穿戴设备,都可以借助已有的库再加上简短的代码实现。这恐怕是Python程序员最幸福的地方了。

当然,Python也有让人痛苦的地方。Python当前最新的版本是3,但Python 3与Python 2不兼容。由于很多现存的代码是Python 2编写的,所以从版本2到版本3的过渡并不容易。许多人选择了继续使用Python 2。有人开玩笑说,Python 2的版本号会在未来增加到2.7.31415926。除了版本选择上的问题,Python的性能也不时被人诟病。Python的运算性能低于C和C++,我们会在本书中提及其原因。尽管Python也在提高自身的性能,但性能的差距会一直存在。不过从Python的发展历史来看,类似的批判其实是吹毛求疵。Python本身就是用性能来交换易用性,走的就是和C、C++相反的方向。说一个足球前锋的守门技术不好,并没有太大的意义。

对于初学编程的人来说,从Python开始学习编程的好处很多,如上面已经提到的语法简单和模块丰富。国外许多大学的计算机导论课程,都开始选择Python作为课程语言,替代了过去常用的C或Java。但如果把Python当作所谓的“最好的语言”,希望学一门Python就成为“万人敌”,则是一种幻想。每个语言都有它优秀的地方,但也有各种各样的缺陷。一个语言“好与不好”的评判,还受制于平台、硬件、时代等外部原因。更进一步,很多开发工作需要特定的语言,比如用Java来编写安卓应用,用Objective-C或Swift来编写苹果应用。无论从哪一门语言学起,最终都不会拘泥于初学的那门语言。只有博彩众家,才能让编程的创造力自由发挥。1.4 最简单的Hello World

Python的安装很方便,可以参考本章的附录A。运行Python的方式有两种。如果你想尝试少量程序,并立即看到结果,则可以通过命令行(Command Line)来运行Python。所谓的命令行,就是一个等着你用键盘来打字的小输入栏,可以直接与Python对话。

按照附录A的方法启动命令行,就进入了Python。通常来说,命令行都会有>>>字样的提示符,提醒你在提示符后面输入。你输入的(7)Python语句会被Python的解释器(interpreter)转化成计算机指令。我们现在执行一个简单的操作:让计算机屏幕显示出一行字。在命令行提示符后面输入下列文字,并按键盘上的回车键(Enter)确认:>>>print("Hello World!")

可以看到,屏幕上会随后显示:Hello World!

输入的print是一个函数的名称。函数有特定的功能,print()函数的功能就是在屏幕上打印出字符。函数后面有一个括号,里面说明了想要打印的字符是"Hello World! "。括号里的一对双引号并没有打印在屏幕上。这一对双引号的作用是从print之类的程序文本中出标记出普通字符,以免计算机混淆。也可以用一对单引号替换双引号。

使用Python的第二种方式是写一个程序文件(Program File)。Python的程序文件以.py为后缀,它可以用任何文本编辑器来创建和编写。附录A中说明了不同操作系统下常用的文本编辑器。创建文件hello.py,写入如下内容,并保存:print("Hello World!")

可以看到,这里的程序内容和用命令行时一模一样。与命令行相比,程序文件适用于编写和保存量比较大的程序。

运行程序文件hello.py,可以看到Python同样在屏幕上打印出了Hello World!。程序文件的内容和命令行里敲入的内容一模一样,产生的效果也一样。与命令行直接输入程序相比,程序文件更容易保存和更改,所以常用于编写大量程序。

程序文件的另一个好处是可以加入注释(comments)。注释是一些文字,用来解释某一段程序,也方便其他程序员了解这段程序。所以,注释的内容并不会被当作程序执行。在Python的程序文件中,每一行中从#开始的文字都是注释,我们可以给hello.py加注释:print("Hello World!") # display text on the screen

如果注释的内容较多,在一行里面放不下,那么可以用多行注释(multiline comments)的方法:"""Author: VameiFunction: display text on the screen""" print('Hello World!')

多行注释的标志符是三个连续的双引号。多行注释也可以使用三个连续的单引号。两组引号之间的内容,就是多行注释的内容。

无论是想要打印的字符,还是用于注释的文字,都可以是中文。如果在Python 2中使用中文,则需要在程序开始之前加上一行编码信息,以说明程序文件中使用了支持中文的utf-8编码。在Python 3中不需要这一行信息。# -*- coding: utf-8 -*- print("你好,世界!") # 在屏幕上显示文字

就这样,我们写出了一个非常简单的Python程序。不要小看了这个程序。在实现这个程序的过程中,你的计算机进行了复杂的工作。它读取了程序文件,在内存中分配了空间,进行了许多运算和控制,最终才控制屏幕的显像原件,让它显示出一串字符。这个程序的顺利运行,说明计算机硬件、操作系统和语言编译器都已经安装并设置好。因此,程序员编程的第一个任务,通常都是在屏幕上打印出Hello (8)World。第一次遇见Python的世界,就用Hello World和它打声招呼吧。附录A Python的安装与运行1.官方版本安装

1)Mac

Mac系统上已经预装了Python,可以直接使用。如果想要使用其(9)他版本的Python,建议使用Homebrew安装。打开终端(Terminal),在命令行提示符后输入下面命令后,将进入Python的可以互动的命令行:$python

上面输入的python通常是一个软链接,指向某个版本的Python命令,如3.5版本。如果相应版本已经安装,那么可以用下面的方式来运行:$python3.5

终端会出现Python的相关信息,如Python的版本号,然后就会出现Python的命令行提示符>>>。如果想要退出Python,则输入:>>>exit()

如果想要运行当前目录下的某个Python程序文件,那么在python或python3后面加上文件的名字:$python hello.py

如果文件不在当前目录下,那么需要说明文件的完整路径,如$python /home/vamei/hello.py

我们还可以把Python程序hello.py改成一个可执行的脚本。只需在hello.py的第一行加上所要使用的Python解释器:#!/usr/bin/env python

在终端中,把hello.py的权限改为可执行:$chmod 755 hello.py

然后在命令行中,输入程序文件的名字,就可以直接使用规定的解释器运行了:$./hello.py

如果hello.py在默认路径下,那么系统就可以自动搜索到这个可执行文件,就可以在任何路径下运行这个文件了:$hello.py

2)Linux操作系统

Linux系统与Mac系统比较类似,大多也预装了Python。很多Linux系统下都提供了类似于Homebrew的软件管理器,例如在Ubuntu下使用下面命令安装:$sudo apt-get install python

在Linux下,Python的使用和运行方式也和Mac系统下类似,这里不再赘述。

3)Windows操作系统(10)

对于Windows操作系统来说,需要到Python的官方网站下载安装包。如果无法访问Python的官网,那么可以通过搜索引擎查找“python Windows下载”这样的关键字,来寻找其他的下载源。安装过程与安装其他Windows软件类似。在安装界面中,选择Customize来个性化安装,除了选择Python的各个组件外,还要勾选:Add python.exe to Path

安装好之后,就可以打开Windows的命令行,像在Mac中一样使用Python了。2.其他Python版本

官方版本的Python主要提供了编译/解释器功能。其他一些非官方版本则有更加丰富的功能和界面,比如更加友好的图形化界面、一个针对Python的文本编辑器,或者是一个更容易使用的模块管理系统,方便你找到各种拓展模块等。在非官方的Python中,最常用的有下面两个:(11)

1)Anaconda(12)

2)Enthought Python Distribution(EPD)

相对于官方版本的Python来说,这两个版本都更容易安装和使用。在模块管理系统的帮助下,程序员还可以避免模块安装方面的恼人问题。所以非常推荐初学者使用。Anaconda是免费的,EPD则对于学生和科研人员免费。由于提供了图形化界面,因此它们的使用方法也相当直观。我强烈建议初学者从这两个版本中挑选一个使用。具体用法可以参考官方文档,这里不再赘述。附录B virtualenv

一台计算机中可以安装多个版本的Python,而使用virtualenv则可给每个版本的Python创造一个虚拟环境。下面就使用Python附带的(13)pip来安装virtualenv:$pip install virtualenv

你可以为计算机中某个版本的Python创建一个虚拟空间,比如:$virtualenv –p /usr/bin/python3.5 myenv

上面的命令中,/usr/bin/python3.5是解释器所在的位置,myenv是新建的虚拟环境的名称。下面命令可开始使用myenv这个虚拟环境:$source myenv/bin/activate

使用下面命令可退出虚拟环境:$deactivate————————————————————

(1) 很多语言使用{}来表示程序块,比如C、Java和JavaScript。

(2) 这部电视剧是《蒙提·派森的飞行马戏团》(Monty Python's Flying Circus)。这部英国喜剧在当时广受欢迎。蒙提·派森是主创剧团的名字。Python即来自这里的“派森”。

(3) 即.so文件。

(4) 罗苏姆充当了社区的决策者。因此,他被称为仁慈的独裁者(Benevolent Dictator For Life)。在Python早期,不少Python追随者担心罗苏姆的生命。他们甚至热情讨论:如果罗苏姆出了车祸,Python会怎样。

(5) python.org

(6) Python Software Foundation

(7) Python的解释器是一个运行着的程序。它可以把Python语句一行一行地直接转译运行。

(8) Hello World!之所以流行,是因为它被经典编程教材《C程序设计语言》用作例子。

(9) Homebrew是Mac下的软件包管理工具,其官方网址为:http://brew.sh/。

(10) Python官网:www.python.org。

(11) Anaconda官网:www.continuum.io。

(12) EPD官网:www.enthought.com/products/epd/。

(13) 将在第3章的附录部分进一步讲解pip的使用。第2章先做键盘侠2.1 计算机会算术2.2 计算机记性好2.3 计算机懂选择2.4 计算机能循环附录A 小练习附录B 代码规范

本章将讲述运算、变量、选择结构和循环结构。常见的高级语言都提供这些语法。利用这些语法,我们也能利用计算机实现一些小型的程序,从而让编程立即应用于生活。例如,平时做数学运算,可以习惯性地用Python的命令行做计算器。敲几行程序,实现一个小功能,就已经能让人享受编程的乐趣了。2.1 计算机会算术1.数值运算

既然名为“计算机”,那么数学计算自然是计算机的基本功。Python中的运算功能简单且符合直觉。打开Python命令行,输入如下的数值运算,立刻就能进行运算:>>>1 + 9 # 加法。结果为10>>>1.3 – 4 # 减法。结果为-2.7>>>3*5 # 乘法。结果为15>>>4.5/1.5 # 除法。结果为3.0>>>3**2 # 乘方,即求3的二次方。结果为9 >>>10%3 # 求余数,就求10除以3的余数。结果为1

有了这些基础运算后,我们就可以像用一个计算器一样使用Python。以买房为例。一套房产的价格为86万元,购买时需要付15%的税,此外还要向银行支付20%的首付。那么我们可以用下面代码计算出需要准备的现金:>>>860000*(0.15 + 0.2) # 结果为301000.0,即30万1千元

除了常见的数值运算,字符串也能进行加法运算。其效果是把两个字符串连成一个字符串:>>>"Vamei say:" + "Hello World" # 连接成"Vamei say:Hello World!"

一个字符串还能和一个整数进行乘法运算:>>>"Vamei"*2 # 结果为"VameiVamei"

一个字符串与一个整数n相乘的话,会把该字符串重复n次。2.逻辑运算

除了进行数值运算外,计算机还能进行逻辑运算。如果玩过杀人游戏,或者喜欢侦探小说,那么就很容易理解逻辑。就好像侦探福尔摩斯一样,我们用逻辑去判断一个说法的真假。一个假设性的说法被称为命题,比如说“玩家甲是杀手”。逻辑的任务就是找出命题的真假。

第1章中已经提到,计算机采用了二进制,即用0和1来记录数据。计算机之所以采用二进制,是有技术上的原因。许多组成计算机的原件,都只能表达两个状态,比如电路的开和关、或者电压的高和低。这样造出的系统也相对稳定。如果使用十进制,那么某些计算机原件就要有10个状态,比如把电压分成十个档。那样的话,系统就会变得复杂且容易出错。在二进制体系下,可以用1和0来代表“真”和“假”两种状态。在Python中,我们使用True和False两个关键字来表示真假。True和False这样的数据被称为布尔值(Boolean)。

有的时候,我们需要进一步的逻辑运算,从而判断复杂命题的真假。比如第一轮时我知道了“玩家甲不是杀手”为真,第二轮我知道了“玩家乙不是杀手”也是真。那么在第三轮时,如果有人说“玩家甲不是杀手,而且玩家乙也不是杀手”,那么这个人就是在说真话。用“而且”连接起来的两个命题分别为真,那么整体命题就是真。无形中,我们进行了一次“与”的逻辑运算。在“与”运算中,两个子命题必须都为真时,用“与”连接起来的复合命题才是真。“与”运算就像是接连的两座桥,必须两座桥都通畅,才能过河,如图2-1所示。以“中国在亚洲,而且英国也在亚洲”这个命题为例。“英国在亚洲”这个命题是假的,所以整个命题就是假的。在Python中,我们用and来表示“与”的逻辑运算。>>>True and True # 结果为True>>>False and True # 结果为False>>>False and False # 结果为False图2-1 “与”和“或”运算

我们还可以用“或者”把两个命题复合在一起。与咄咄逼人的“而且”关系相比,“或者”显得更加谦逊。比如在“中国在亚洲,或者英国在亚洲”这个说法中,说话的人就给自己留了余地。由于这句话的前一半是对的,所以整个命题就是真的。“或者”就对应了“或”逻辑运算。在“或”运算中,只要有一个命题为真,那么用“或”连接起来的复合命题就是真。“或”运算就像并行跨过河的两座桥,任意一座通畅,就能让行人过河。

Python用or来进行“或”的逻辑运算。>>>True or True # 结果为True>>>True or False # 结果为True>>>False or False # 结果为False

最后,还有一种称为非的逻辑运算,其实就是对一个命题求反。比如“甲不是杀手”为真,那么“甲是杀手”这个反命题就是假。Python使用not这个关键字来表示非运算,比如:>>>not True # 结果为False3.判断表达式

上面的逻辑运算看起来似乎只是些生活经验,完全不需要计算机这样的复杂工具。加入判断表达式之后,逻辑运算方能真正显示出它的威力。

判断表达式其实就是用数学形式写出来的命题。比如“1等于1”,写在Python里就是:>>>1 == 1 # 结果为True

符号==表示了相等的关系。此外,还有其他的判断运算符:>>>8.0 != 8.0 # !=, 不等于>>>4 < 5 # <, 小于>>>3 <= 3 # <=, 小于或等于>>>4 > 5 # >, 大于>>>4 >= 0 # >=, 大于等于

这些判断表达式都很简单。即使不借助Python,也能很快在头脑中得出它们的真假。但如果把数值运算、逻辑运算和判断表达式放在一起,就能体现出计算机的优势了。还是用房贷的例子,房产价格86万元,税率15%,首付20%。假如我手里有40万元的现金。出于税务原因,我还希望自己付的税款低于13万元,那么是否还可以买这套房子?这个问题可以借用Python进行计算。>>>860000*(0.15 + 0.2) <= 400000 and 860000*0.15 < 130000

答案是True,可以买房!4.运算优先级

如果一个表达式中出现多个运算符,就要考虑运算优先级的问题。不同的运算符号优先级不同。运算符可以按照优先级先后归为:乘方:**乘除:* /加减:+ -判断:== >>= <<=逻辑:! and or

如果是相同优先级的运算符,那么Python会按照从左向右的顺序进行运算,比如:>>>4 + 2 - 1 # 先执行加法,再执行减法。结果为5

如果有优先级高的运算符,Python会打破从左向右的默认次序,先执行优先级高的运算,比如:>>>4 + 2*2 # 先执行乘法,再执行加法。结果为8

括号会打破运算优先级。如果有括号存在,会先进行括号中的运算:>>>(4 + 2)*2 # 先执行加法,再执行乘法。结果为122.2 计算机记性好1.变量革命

上面的运算中出现的数据,无论是1和5.2这样的数值,还是True和False这样的布尔值,都会在运算结束后消失。有时,我们想把数据存储到存储器中,以便在后面的程序中重复使用。计算机存储器中的每个存储单元都有一个地址,就像是门牌号。我们可以把数据存入特定门牌号的隔间,然后通过门牌号来提取之前存储的数据。

但用内存地址来为存储的地址建索引,其实并不方便:● 内存地址相当冗长,难以记忆。● 每个地址对应的存储空间大小固定,难以适应类型多变的数据。● 对某个地址进行操作前,并不知道该地址的存储空间是否已经被

占用。

随着编程语言的发展,开始有了用变量的方式来存储数据。变量和内存地址类似,也起到了索引数据的功能。新建变量时,计算机在空闲的内存中开辟存储空间,用来存储数据。和内存地址不同的是,根据变量的类型,分配的存储空间会有大小变化。程序员给变量起一个变量名,在程序中作为该变量空间的索引。数据交给变量,然后在需要的时候通过变量的名字来提取数据。比如下面的Python程序:v = "Vivian"print(v) #打印出"Vivian"

在上面的程序中,我们把数值10交给变量v保存,这个过程称为赋值(Assignment)。Python中用等号=来表示赋值。借助赋值,一个变量就建立了。从硬件的角度来看,给变量赋值的过程,就是把数据存入内存的过程。变量就像能装数据的小房间,变量名是门牌号。赋值操作是让某个客人前往该房间。“让Vivian入住到v字号房。”

在随后的加法运算中,我们通过变量名v取出了变量所包含的数据,然后通过print()打印出来。变量名是从内存中找到对应数据的线索。有了存储功能,计算机就不会犯“失忆症”了。“v字号房住的是谁?”“是Vivian呀。”

酒店的房间会有不同的客人入住或离开。变量也是如此。我们可以给一个变量赋其他的值。这样,房间里的客人就变了。v = "Tom"print(v) #打印出"Tom"

在计算机编程时,经常设置许多变量,让每个变量存储不同功能的数据。例如,电脑游戏中可能记录玩家拥有的不同资源的数目,就可以用不同的变量记录不同的资源。gold = 100 # 100个金子wood = 20 # 20个木材wheat = 29 # 29个小麦

在游戏过程中,可以根据情况增加或者减少某种资源。例如,玩家选择伐木,就增加5个木材。这个时候,就可以对相应变量执行加5的操作。wood = wood + 5print(wood) # 打印出25

计算机先执行赋值符号右边的运算。原有的变量值加5,再赋予给同一个变量。在游戏进行的整个过程中,变量wood起到了追踪木材数据的作用。玩家的资源数据被妥善地存储起来。

变量名直接参与运算,这是迈向抽象思维的第一步。在数学上,用符号来代替数值的做法称为代数。今天的很多中学生都会列出代数方程,来解决“鸡兔同笼”之类的数学问题。但在古代,代数是相当先进的数学。欧洲人从阿拉伯人那里学到了先进的代数,利用代数的符号系统,摆脱了具体数值的桎梏,更加专注于逻辑和符号之间的关系。在代数的基础上发展出近代数学,为近代的科技爆炸打下了基础。变量也让编程有了更高一层的抽象能力。

变量提供的符号化表达方式,是实现代码复用的第一步。比如之前计算购房所需现金的代码:860000*(0.15 + 0.2)

当我们同时看多套房时,860000这个价格会不断变动。为了方便,我们可以把程序写成:total = 860000requirement = total*(0.15 + 0.2)print(requirement) # 打印结果301000.0

这样,每次在使用程序时,只需更改860000这个数值就可以了。当然,我们还会在未来看到更多的复用代码的方式。但变量这种用抽象符号代替具体数值的思维,具有代表性的意义。2.变量的类型

数据可能有很多不同的类型,例如5这样的整数、5.9这样的浮点数、True和False这样的布尔值,还有第1章中见过的字符串"Hello World!"。在Python中,我们可以把各种类型的数据赋予给同一个变量。比如:var_integer = 5print(var_integer) # a存储的内容为整数5var_string = "Hello World!"print(var_string) # a存储的内容变成字符串"Hello World!"

可以看到,后赋予给变量的值替换了变量原来的值。Python能自由改变变量类型的特征被称为动态类型(Dynamic Typing)。并不是所有的语言都支持动态类型。在静态类型(Static Typing)的语言中,变量有事先说明好的类型。特定类型的数据必须存入特定类型的变量。相比于静态类型,动态类型显得更加灵活便利。

即使是可以自由改变,Python的变量本身还是有类型的。我们可

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载