Python基础教程(第3版)(txt+pdf+epub+mobi电子书下载)


发布时间:2020-07-01 20:29:47

点击下载

作者:Magnus Lie Hetland

出版社:人民邮电出版社

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

Python基础教程(第3版)

Python基础教程(第3版)试读:

前言

1

巨蟒剧团有首老歌唱道:“又来了一个,它走了又来。又来了一个,什么时候是个头?”自本书第2版面世以来,Python 3的普及程度得到了极大提高,因此这一版完全转向了Python 3。在此期间,还有其他的变化:在Python生态系统中,各种包轮番登场,各种编码实践大行其道后又日渐式微。在必要之处或对读者有帮助的前提下,本书的有些部分完全重写,但最初的痕迹还依稀可见。例如,本书前身Practical Python于21世纪初出版时,Usenet依然应用广泛,可现在大多数互联网用户可能从未听说过它。因此,对于第23章创建连接到NNTP服务器的项目,与其说是为了介绍主流编程生涯中将用到的编程技能,不如说是让读者了解一下历史。一些比较古怪的内容也依旧保留,因为它们是很不错的编程示例,也是本书悠长历史的见证。1Monty Python,英国的一个超现实幽默表演团体,喜剧界的披头士,在20世纪70年代风靡全球。Python语言的命名来源于此。——编者注

与以往一样,我要深深地感谢让本书以前各版得以付梓的人。这里我要特别感谢Mark Powers,感谢他在我进度缓慢时极具耐心。还要感谢Michael Thomas,感谢他出色的技术审阅工作(并指出了原稿中所有的Python 2式print语句)。但愿你喜欢全新升级后的这一版。正如Terny Jones在提到那首老歌时所说:“显然,有一个完整的管弦乐队会更好。”

第2版前言

新版的《Python基础教程》终于和大家见面了。如果算上本书的前身Practical Python,实际上这已经是第3版了。这是我将近10年心血的结晶。在此期间,Python发生了很多有趣的变化,我也尽力调整了对这门语言的介绍。当前,Python处于长期以来最为翻天覆地的转变期:Python 3推出。编写本书期间,最终版本还未发布,但其包含的功能已确定,还推出了多个可用的版本。这次修订不向后兼容,这是我编写这一版时面临的最大挑战。换而言之,我不能仅仅挑出一些新增的功能进行介绍。另外,它还修改了一些既有的功能,因此有些在Python 2.5中理所当然的事情在新版本中已不再正确。

倘若整个Python社区都立即转向Python 3并修改所有的遗留代码,那根本不成问题。我只需介绍Python 3就行!然而,目前依然存在大量用Python 2编写的代码,而且大家可能还会继续编写这样的代码,直到有一天所有人都认为应使用Python 3。

那么我是如何应对这种变化的呢?首先,虽然有些向后兼容的变化,但Python语言本身总体变化不大。因此,如果完全针对Python 2.5,编写的内容对Python 3来说也是大体正确的(对Python 2.6来说更是如此)。至于那些不再正确的部分,我采取了比较保守的态度,因为大家完全接受Python 3还需要一段时间。因此,这一版主要是基于Python 2.5编写的,同时指出将会改变的情形。另外,我还提供了附录D,让你对重大变化有大致的了解。对大多数读者来说,这样处理是完全可行的。

编写这一版期间,有几个人帮了我很大的忙。与前两版(本书第1版以及之前的Practical Python)一样,Jason Gilmore扶我上马,并在项目启动期间扮演了重要角色。项目启动后,Richard Dal Porto、Frank Pohlmann和Dominic Shakeshaft不断伸出援手,保证项目得以顺利进行。在确保代码正确方面,Richard Taylor居功至伟(倘若代码依然存在错误,责任在我),而Marilyn Smith出色地完成了手稿润色工作。这里还要感谢Apress出版社的其他工作人员,他们是Liz Berry、Beth Christmas、Steve Anglin和Tina Nielsen。另外,感谢包括Bob Helmbold和Waclaw Kusnierczyk在内的读者提出勘误和宝贵的建议。最后,在本书前两版的出版过程中,很多人都提供了帮助,这里衷心地感谢他们。

第1版前言

几年前,Jason Gilmore找到我,让我为Apress出版社写本书。他看了我撰写的Python在线教程,想让我写一本风格类似的书。我受宠若惊,既兴奋又有点紧张。我最关心的是,这需要多长时间、对学业会有多大的影响,因为当时我正在读博士。结果表明,这是一项非常艰巨的任务,花费的时间远远超出了预期。

所幸这对我的学业没有太大的影响,我按时获得了博士学位。

去年,Jason又找到我说,Apress出版社想让我对原书进行修订和扩充,不知道我是否有兴趣。当时我正忙于熟悉新取得的副教授职位,而业余时间都花在了扮演Peer Gynt上,因此时间依然是主要的问题。事情安排妥当并有更多业余时间后,我接受了这项任务。你可能猜到了,最终的结晶就是你现在手捧的这本书。本书的大多数内容都来自Practical Python,但基于Python的最新变化做了全面修订,同时新增了几章。另外,根据这一版的组织结构,调整了原来一些内容的位置。很多读者对Practical Python提供了积极的反馈,但愿本版保留了读者喜欢的内容,同时新增的内容也能得到读者青睐。

本书编写期间,有几个人不断地给予我帮助和鼓励。没有他们,本书根本不可能付梓。这里对他们表示衷心的感谢。感谢本书编写期间直接与我协作的团队:Jason Gilmore让这个项目得以上马并确保不偏离方向;Beckie Stones整理各种材料;Jeremy Jones和Matt Moodie提供了专业的意见和见解;Linda Marousek对我极具耐心;还有其他成员让本书得以顺利出版。如果没有Practical Python打下的基础,本书不会是现在这个样子。这里要感谢Jason Gilmore和Alex Martelli出色的技术编辑工作(Jason负责全书,Alex负责前半部分)以及本职之外的各种意见和建议。感谢Erin Mulligan和Tory McLearn一路上领我前行,并在需要时让我调整方向。感谢Nancy Rapoport对手稿进行润色。感谢Grace Wong回答他人无法回答的问题。感谢Pete Shinners就项目10的游戏提供宝贵的建议。感谢多位读者的来信,这些来信给了我极大的鼓励!最后,感谢我的家人和朋友,尤其是女朋友Ranveig在本书编写期间给予的宽容。

引言

C程序犹如拿着剃刀在刚打过蜡的地板上劲舞。——Waldi Ravens

 C++学起来很难,因为它天生如此。——佚名

 Java从很多方面来说,就是简化版的C++。——Michael Feldman

 接下来请欣赏与众不同的表演。——巨蟒剧团之《飞翔的马戏团》

前面引用了别人的几句话,旨在为本书定下基调,就是不那么严肃正式。为让本书阅读起来轻松愉快,我力图以幽默的方式来讨论Python编程这个主题。幽默是Python社区的传统,而这种幽默在很大程度上与巨蟒剧团的短剧相关。因此,本书的有些示例看起来有点傻,但愿你能容忍。[顺便说一句,Python来源于巨蟒剧团(Monty Python),而不是蟒蛇。]这里将简单地说说Python是什么,为何要使用它,有哪些人在使用它,本书为谁而写,并概述本书的组织结构。

Python是什么?为何要使用它?官方宣传说:Python是一种面向对象的解释性高级编程语言,具有动态语义。这句话中有很多术语,在阅读本书的过程中,你会逐渐了解其含义。这句话的要点在于,Python是一种知道如何不妨碍你编写程序的编程语言。它让你能够毫无困难地实现所需的功能,还让你能够编写出清晰易懂的程序(与使用当前流行的其他大多数编程语言相比,编写出来的程序要清晰易懂得多)。

虽然Python的速度可能没有C、C++等编译型语言那么快,但它能够节省编程时间。仅考虑到这一点就值得使用Python,况且对大多数程序而言,速度方面的差别并不明显。如果你是C语言程序员,那么你可轻松地使用C语言实现程序的重要部分,再将其与Python部分整合起来。如果你没有任何编程经验(并对我提及C和C++感到有点迷惑),那么简洁而强大的Python就是你进入编程殿堂的理想选择。

那么,有哪些人在使用Python呢?从Guido van Rossum于20世纪90年代初创造这门语言起,其追随者就在不断增加,最近几年尤其如此。Python广泛用于完成系统管理任务(例如,它是多个Linux发行版的重要组成部分),也被用来向新手介绍编程。NASA使用它来完成开发工作,并在多个系统中将其用作脚本语言;工业光魔公司在预算庞大的故事片中使用Python来制作特效;Yahoo!使用它(以及其他技术)来管理讨论组;Google使用它实现了网络爬虫和搜索引擎的众多组件。Python还被用于计算机游戏和生物信息等众多领域。不久后可能就会有人问:有谁不使用Python呢?

本书是为有志于学习Python编程的人写的,适合从编程门外汉到计算机高手的各种读者阅读。如果你没有任何编程经验,应从第1章开始阅读,阅读到看不懂的内容后,开始动手编写一些程序。等到条件成熟后,再回过头来继续阅读更复杂的内容。

如果你熟悉编程,对有些基础知识可能并不陌生(但书中会不时出现令你意外的细节),因此可大致浏览前几章,以便对Python的工作原理有大致认识。当然,也可通读附录A。它是根据Python在线教程“Instant Python”改编而来的,让你能够快速了解最重要的Python概念。对它有大致认识后,可直接跳到第10章,去学习Python标准库。

本书的最后10章是10个编程项目,展示了Python语言的各种功能。无论你是初学者还是专家,都应该会对这些项目感兴趣。虽然对经验不那么丰富的程序员来说,最后几个项目理解起来有点难,但阅读本书的前半部分之后,完全能够按说明完成这些项目。

这些项目涉及众多主题,掌握这些主题对你自己动手编写程序大有裨益。你将学习如何完成一些现在看起来根本无法完成的任务,如创建聊天服务器、点对点文件共享系统和功能齐备的图形计算机游戏。这些任务乍一看好像很难,但最终你将发现,它们实际上大多容易得难以置信。如果你想下载源代码,可访问Apress网站(http://1www.apress.com)。1图灵社区本书页面也提供源代码下载:http://www.ituring.com.cn/book/2118。——编者注

就说这么多。冗长的引言总是让我觉得有点烦,现在就开始Python编程吧——从第1章或附录A开始。祝你好运,编程愉快!第1章快速上手:基础知识

该动手实践了。在本章中,你将学习如何借助计算机能够听懂的语言——Python——来控制它。这里没有什么太难的内容,只要了解计算机的基本工作原理,就能按部就班地完成本章的示例。我将从最简单的内容着手介绍一些基本知识,但鉴于Python功能强大,你很快就能完成一些非常复杂的任务。

首先,需要安装Python或核实已经安装了它。如果你使用的是macOS或Linux/UNIX,请打开终端(在Mac中为应用程序Terminal),输入python并按回车键。你将看到一条欢迎消息,其末尾为如下提示符:>>>

如果情况确实如此,就可以输入Python命令了,但需要注意的是,你的系统安装的可能是较旧的Python版本。如果第一行消息的开头为Python 2,而不是Python 3,你可能要安装较新的版本,因为Python 3在多个方面发生了翻天覆地的变化。

具体的安装步骤视使用的操作系统和安装方式而异,但最简单的方法是访问www.python.org,其中有下载页面的链接。安装过程非常简单,不管你使用的是Windows、macOS、Linux/UNIX还是其他操作系统,只需单击链接就可访问相应的最新版本。如果你使用的是Windows或Mac,将下载一个安装程序,可通过运行它来安装Python。如果你使用的是Linux/UNIX,将下载到源代码压缩文件,需要按说明进行编译,但通过使用Homebrew、APT等包管理器,可简化安装过程。

安装Python后,尝试启动交互式解释器。要从命令行启动Python,只需执行命令python。如果同时安装了较旧的版本,可能需要执行命令python3。如果你更喜欢使用图形用户界面,可启动Python自带的应用程序IDLE。1.1 交互式解释器

启动Python后,可看到类似于下面的提示符:Python 3.5.0 (default, Dec 5 2015, 15:03:35)[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.1.76)] on darwinType "help", "copyright", "credits" or "license" for more information.>>>

解释器的外观及其显示的错误消息因版本而异。虽然看上去没多大意思,但请相信我,这其实很有趣,因为这是进入黑客殿堂的大门——对计算机进行控制的第一步。更准确地说,这是一个交互式Python解释器。请尝试像下面这样做,以核实它是否管用:>>> print("Hello, world!")

等你按下回车键后,将出现如下输出:Hello, world!>>>

如果你熟悉其他计算机语言,可能习惯了在每行末尾都加上分号。在Python中无需这样做,因为在Python中,一行就是一行。如果你愿意,也可加上分号,但不会有任何影响(除非后面还有其他代码),况且大家通常都不这样做。

这是怎么回事呢?>>>是提示符,可在它后面输入一些内容。例如,如果你输入print("Hello, world!")并按回车键,Python解释器将打印字符串"Hello, world!",然后再次显示提示符。

如果输入截然不同的内容呢?请尝试这样做:>>> The Spanish InquisitionSyntaxError: invalid syntax>>>1

显然,解释器没有看懂(如果你运行的不是IDLE,而是Linux命令行解释器,错误消息可能稍有不同)。解释器还指出了问题出在什么地方:使用红色背景色(在命令行解释器中,使用的是脱字符号^)突出单词Spanish。1

毕竟,谁都没想到遇上了西班牙宗教裁判所(Spanish Inquisition)。

如果你喜欢这个解释器,可再尝试几次(要获取使用指南,可在提示符下输入命令help()并按回车键。在IDLE中,还可按F1来获取帮助信息),否则请接着往下读。毕竟,在不知道如何与之交流的情况下,这个解释器并不是很有趣。1.2 算法是什么

真刀真枪地编写程序前,先来说说何为计算机编程。简而言之,计算机编程就是告诉计算机如何做。计算机多才多艺,但不太善于独立思考,我们必须提供详尽的细节,使用它们能够明白的语言将算法提供给它们。算法只不过是流程或菜谱的时髦说法,详尽地描述了如何完成某项任务。请看下面的菜谱:鸡蛋火腿肠:先取一些火腿肠。再加些火腿肠和鸡蛋。如果喜欢吃辣,加些辣味火腿肠。煮熟为止。记得每隔10分钟检查一次。

这个菜谱并不神奇,但其结构很有启发性。它由一系列必须按顺序执行的操作说明组成,其中有些可直接完成(取些火腿肠),有些需要特别注意(如果喜欢吃辣),还有一些需要重复多次(每隔10分钟检查一次)。

菜谱和算法都由原料(对象)和操作说明(语句)组成。在这个示例中,火腿肠和鸡蛋是原料,而操作说明包括添加火腿肠、烹饪指定的时间等。下面首先介绍一些非常简单的Python原料,看看可以对它们做些什么。1.3 数和表达式

交互式Python解释器可用作功能强大的计算器。请尝试执行如下操作:>>> 2 + 2

结果应该为4,这不难。下面的运算呢?>>> 53672 + 235253288925

还是觉得没什么?不可否认,这是很常见的运算。(下面假设你对如何使用计算器很熟悉,知道1 + 2 * 3和(1 + 2) * 3有何不同。)所有常见算术运算符的工作原理都与你预期的一致。除法运算的结果为小数,即浮点数(float或floating-point number)。>>> 1 / 20.5>>> 1 / 11.0

如果你想丢弃小数部分,即执行整除运算,可使用双斜杠。>>> 1 // 20>>> 1 // 11>>> 5.0 // 2.42.0

在较旧的Python版本中,对整数执行常规除法运算的结果与使用双斜杠类似。如果你使用的是Python 2.x,要对整数执行常规除法运算,可在程序开头添加如下语句(稍后介绍如何编写完整的程序),也可直接在交互式解释器中执行这条语句:>>> from __future__ import division注意 在上述语句中,future前后分别是两条下划线:__future__。

另外,从命令行运行较旧的Python版本时,还可使用命令行开关-Qnew。1.8.2节将更详尽地介绍__future__。

至此,你了解了基本的算术运算符(加法、减法、乘法和除法),但还有一种与整除关系紧密的运算没有介绍。>>> 1 % 21

这是求余(求模)运算符。x % y的结果为x除以y的余数。换而言之,结果为执行整除时余下的部分,即x % y等价于x - ((x // y) * y)。>>> 10 // 33>>> 10 % 31>>> 9 // 33>>> 9 % 30>>> 2.75 % 0.50.25

在这里,10 // 3为3,因为结果向下圆整,而3 × 3为9,因此余数为1。将9除以3时,结果正好为3,没有向下圆整,因此余数为0。在需要执行之前菜谱指定的“每10分钟检查一次”之类的操作时,这种运算可能很有用:只需检查minute % 10是否为0。(有关如何执行这种检查,请参阅本章后面的旁注“先睹为快:if语句”。)从最后一个示例可知,求余运算符也可用于浮点数。这种运算符甚至可用于负数,但可能不那么好理解。>>> 10 % 31>>> 10 % -3-2>>> -10 % 32>>> -10 % -3-1

你也许不能通过这些示例一眼看出求余运算的工作原理,但通过研究与之配套的整除运算可帮助理解。>>> 10 // 33>>> 10 // -3-4>>> -10 // 3-4>>> -10 // -33

基于除法运算的工作原理,很容易理解最终的余数是多少。对于整除运算,需要明白的一个重点是它向下圆整结果。因此在结果为负数的情况下,圆整后将离0更远。这意味着对于-10 // 3,将向下圆整到-4,而不是向上圆整到-3。

这里要介绍的最后一个运算符是乘方(求幂)运算符。>>> 2 ** 38>>> -3 ** 2-9>>> (-3) ** 29

请注意,乘方运算符的优先级比求负(单目减)高,因此-3**2等价于-(3**2)。如果你要计算的是(-3)**2,必须明确指出。十六进制、八进制和二进制

结束本节前需要指出的是,十六进制数、八进制数和二进制数分别以下面的方式表示:>>> 0xAF175>>> 0108>>> 0b1011010010722

这些表示法都以0打头。(如果你不明白这些表示法有何意义,说明你使用它们的机会不多,只需将其牢记在心即可。)1.4 变量

另一个你可能熟悉的概念是变量(variable)。如果代数对你来说不过是遥远的记忆,也不用担心,因为Python中的变量理解起来很容易。变量是表示(或指向)特定值的名称。例如,你可能想使用名称x来表示3,为此执行如下代码:>>> x = 3

这称为赋值(assignment),我们将值3赋给了变量x。换而言之,就是将变量x与值(或对象)3关联起来。给变量赋值后,就可在表达式中使用它。>>> x * 26

不同于其他一些语言,使用Python变量前必须给它赋值,因为Python变量没有默认值。注意 在Python中,名称(标识符)只能由字母、数字和下划线(_)构成,且不能以数字打头。因此Plan9是合法的变量名,2而9Plan不是。2在某种程度上说,标识符命名规则基于Unicode标准,详情请参阅“Python语言参考手册”(https://docs.python.org/3/reference/lexical_analysis.html)。1.5 语句

前面使用的几乎都是表达式,相当于菜谱中的原料,但语句(菜谱中的操作说明)是什么样的呢?

实际上,刚才说的不完全正确,因为前面已经介绍过两种语句了:print语句和赋值语句。语句和表达式有何不同呢?你可以这样想:表达式是一些东西,而语句做一些事情。例如,2 * 2的结果是4,而print(2 * 2)打印4。表达式和语句的行为很像,因此它们之间的界线可能并非那么明确。>>> 2 * 24>>> print(2 * 2)4

在交互式解释器中执行时,这两段代码的结果没有任何差别,但这是因为解释器总是将表达式的值打印出来(打印的是repr表示的内容,详情请参阅1.10.3节)。然而,在Python中,情况并非都是这样的。本章后面将介绍如何创建无需交互式解释器就能运行的程序。仅3将诸如2 * 2等表达式放在程序中不会有任何作用,但在程序中包含print(2 * 2)将打印结果4。3这个表达式确实会执行一些操作:计算2和2的乘积。但既不会将结果保存起来,也不会向用户显示它。因此除执行计算外,没有其他任何作用。注意 print实际上是一个函数(这将在本章后面更详细地介绍),因此前面说的print语句其实是函数调用。在Python 2.x 中,print是一条语句,无需将要打印的内容作为参数放在圆括号内。

涉及赋值时,语句和表达式的差别更明显:鉴于赋值语句不是表达式,它们没有可供交互式解释器打印的值。>>> x = 3>>>

执行赋值语句后,交互式解释器只是再次显示提示符,但发生了一些变化:有一个名为x的新变量,与值3相关联。可以说,这是所有语句的一个根本特征:执行修改操作。例如,赋值语句改变变量,而print语句改变屏幕的外观。

无论在什么编程语言中,赋值语句都可能是最重要的语句,虽然这一点你可能难以马上明白。变量就像是临时“存储区”(类似于菜4谱中的锅碗瓢盆),其真正威力在于无需知道它们存储的值就能操作它们。4请注意,这里给“存储区”加上了引号。值并非存储在变量中,而是存储在变量指向的计算机内存中。多个变量可指向同一个值。深入阅读后会更清楚地了解这一点。

例如,即便根本不知道x和y是什么,你也知道x * y的结果为x和y的乘积。因此,编写程序时,你能以各种方式使用变量,而无需知道程序运行时它们将存储(指向)的值。1.6 获取用户输入

前面说过,编写程序时无需知道变量的值就可使用它们。当然,解释器最终必须知道变量的值,可它怎么知道我们不知道的事情呢?解释器只知道我们已告知它的内容,不是吗?未必如此。

你编写的程序可能供他人使用,无法预测用户会向程序提供什么样的值。我们来看看很有用的函数input(稍后将更详细地介绍函数)。>>> input("The meaning of life: ")The meaning of life: 42'42'

这里在交互式解释器中执行了第一行(input(...)),它打印字符串"The meaning of life:",提示用户输入相应的信息。我输入42并按回车。这个数被input(以文本或字符串的方式)返回,并在最后一行被自动打印出来。通过使用int将字符串转换为整数,可编写一个更有趣的示例:>>> x = input("x: ")x: 34>>> y = input("y: ")y: 42>>> print(int(x) * int(y))1428

对于上述在Python提示符(>>>)下输入的语句,可将其放在完整的程序中,并让用户提供所需的值(34和42)。这样,这个程序将打印结果1428,即前述两个数的乘积。在这种情况下,你编写程序时无需知道这些值,对吧?注意 将程序存储在独立的文件中,让其他用户能够执行时,这种获取输入的方式将有用得多。1.8节将介绍如何这样做。

 先睹为快:if语句为增添学习乐趣,这里提前说说原本要到第5章才介绍的内容:if语句。通过使用if语句,可在给定条件满足时执行特定的操作(另一条语句)。一种条件是使用相等运算符(==)表示的相等性检查。没错,相等运算符就是两个等号。(一个等号用于赋值,还记得吗?) 你将条件放在if后面,再加上冒号,将其与后面的语句分开。>>> if 1 == 2: print('One equals two')...>>> if 1 == 1: print('One equals one')...One equals one>>>条件不满足时什么都不做,但条件满足时,将执行冒号后面的语句(这里是一条print语句)。需要注意的另一点是,在交互式解释器中输入if语句后,需要按两次回车键才能执行它(其中的原因将在第5章介绍)。因此,如果变量time指向的是以分钟为单位的当前时间,可使用如下语句检查当前是不是整点:if time % 60 == 0: print('On the hour!')1.7 函数

1.3节使用了乘方运算符(**)来执行幂运算。实际上,可不使用这个运算符,而使用函数pow。>>> 2 ** 38>>> pow(2, 3)8

函数犹如小型程序,可用来执行特定的操作。Python提供了很多函数,可用来完成很多神奇的任务。实际上,你也可以自己编写函数(这将在后面更详细地介绍),因此我们通常将pow等标准函数称为内置函数。

像前一个示例那样使用函数称为调用函数:你向它提供实参(这里是2和3),而它返回一个值。鉴于函数调用返回一个值,因此它们5也是表达式,就像本章前面讨论的算术表达式一样。实际上,你可结合使用函数调用和运算符来编写更复杂的表达式(就像前面使用函数int时那样)。5函数调用也可用作语句,但在这种情况下,将忽略函数的返回值。>>> 10 + pow(2, 3 * 5) / 3.010932.666666666666

有多个内置函数可用于编写数值表达式。例如,abs计算绝对值,round将浮点数圆整为与之最接近的整数。>>> abs(-10)10>>> 2 // 30>>> round(2 / 3)1.0

请注意最后两个表达式的差别。整数总是向下圆整,而round圆整到最接近的整数,并在两个整数一样近时圆整到偶数。如果要将给定的数向下圆整,该如何做呢?例如,你知道某人的年龄为32.9,并想将这个值向下圆整为32,因为他还没有满33岁。Python提供了完成这种任务的函数floor,但你不能直接使用它,因为像众多很有用的函数一样,它也包含在模块中。1.8 模块

可将模块视为扩展,通过将其导入可以扩展Python功能。要导入模块,可使用特殊命令import。前一节提及的函数floor包含在模块math中。>>> import math>>> math.floor(32.9)32

请注意其中的工作原理:我们使用import导入模块,再以module.function的方式使用模块中的函数。就这里执行的操作而言,也可像前面处理input的返回值那样,将这个数字转换为整数。>>> int(32.9)32注意 还有一些类似的函数,可用于转换类型,如str和float。实际上,它们并不是函数,而是类。类将在本书后面更详细地介绍。

模块math还包含其他几个很有用的函数。例如,ceil与floor相反,返回大于或等于给定数的最小整数。>>> math.ceil(32.3)33>>> math.ceil(32)32

如果确定不会从不同模块导入多个同名函数,你可能不想每次调用函数时都指定模块名。在这种情况下,可使用命令import的如下变种:>>> from math import sqrt>>> sqrt(9)3.0

通过使用命令import的变种from module import function,可在调用函数时不指定模块前缀。提示 事实上,可使用变量来引用函数(以及其他大部分Python元素)。执行赋值语句foo = math.sqrt后,就可使用foo来计算平方根。例如,foo(4)的结果为2.0。1.8.1 cmath和复数

函数sqrt用于计算平方根。下面来看看向它提供一个负数的情况:>>> from math import sqrt>>> sqrt(-1)Traceback (most recent call last):...ValueError: math domain error

在有些平台上,结果如下:>>> sqrt(-1)nan注意 nan具有特殊含义,指的是“非数值”(not a number)。

如果我们坚持将值域限定为实数,并使用其近似的浮点数实现,就无法计算负数的平方根。负数的平方根为虚数,而由实部和虚部组成的数为复数。Python标准库提供了一个专门用于处理复数的模块。>>> import cmath>>> cmath.sqrt(-1)1j

注意到这里没有使用from ... import ...。如果使用了这种import命令,将无法使用常规函数sqrt。类似这样的名称冲突很隐蔽,因此除非必须使用from版的import命令,否则应坚持使用常规版import命令。

1j是个虚数,虚数都以j(或J)结尾。复数算术运算都基于如下定义:-1的平方根为1j。这里不深入探讨这个主题,只举一个例子来结束对复数的讨论:>>> (1 + 3j) * (9 + 4j)(-3 + 31j)

从这个示例可知,Python本身提供了对复数的支持。注意 Python没有专门表示虚数的类型,而将虚数视为实部为零的复数。1.8.2 回到未来

据说Python之父Guido van Rossum有一台时光机,因为这样的情况出现了多次:大家要求Python提供某项功能时,却发现这项功能早已实现。当然,并非什么人都能进入这台时光机,不过Guido很体贴,通过神奇模块__future__让Python具备了时光机的部分功能。对于Python当前不支持,但未来将成为标准组成部分的功能,你可从这个模块进行导入。这一点你在1.3节已经见识过,本书后面也将经常遇到这个模块。1.9 保存并执行程序

交互式解释器是Python的亮点之一,它让你能够实时地测试解决方案以及尝试使用Python。要了解隐藏在背后的工作原理,只需尝试使用即可!然而,等你退出交互式解释器时,你在其中编写的所有代码都将丢失。你的终极目标是编写自己和他人都能运行的程序。本节将介绍如何达成这种目标。

首先,你需要一个文本编辑器——最好是专门用于编程的(不推荐使用Microsoft Word之类的软件,但如果你使用的是这样的软件,务必以纯文本的方式保存代码)。如果你使用的是IDLE,那就太幸运了。在这种情况下,只需选择菜单File→New File。这将新建一个编辑器窗口,其中没有交互式提示符。首先,输入如下代码:print("Hello, world!")

接下来,选择菜单File→Save保存程序(其实就是一个纯文本文件)。务必将文件存储在以后能够找到的地方,并指定合理的文件名,如hello.py(扩展名.py很重要)。

保存好了吗?请不要关闭包含程序的窗口。如果关闭了,选择菜单File→Open重新打开。现在可以运行这个程序了,方法是选择菜单Run→Run Module。(如果你使用的不是IDLE,请参阅下一节,了解如何从命令提示符运行程序。)

结果如何呢?在解释器窗口中打印了Hello, world!,这正是我们想要的结果。根据你使用的版本,解释器提示符可能消失,要让它重新出现,可在解释器窗口中按回车键。

接下来,将脚本扩展成下面这样:name = input("What is your name? ")print("Hello, " + name + "!")

如果你运行这个脚本(别忘了先保存),将在解释器窗口中看到如下提示信息:What is your name?

输入你的名字(如Gumby)并按回车键,你将看到类似于下面的内容:Hello, Gumby!强大的海龟绘图法编写简单示例时,print语句很有用,因为几乎在任何地方都可使用它。如果你要尝试提供更有趣的输出,应考虑使用模块turtle,它实现了海龟绘图法。如果你正在运行IDLE,就可使用这个模块,它让你能够绘制图形(而不是打印文本)。通常,应避免导入模块中所有的名称,但尝试使用海龟绘图法时,这样做可提供极大的方便。from turtle import *确定需要使用哪些函数后,可回过头去修改import语句,以便只导入这些函数。海龟绘图法的理念源自形如海龟的机器人。这种机器人可前进和后退,还可向左和向右旋转一定的角度。另外,这种机器人还携带一只铅笔,可通过抬起或放下来控制铅笔在什么时候接触到脚下的纸张。模块turtle让你能够模拟这样的机器人。例如,下面的代码演示了如何绘制一个三角形:forward(100)left(120)forward(100)left(120)forward(100)如果你运行这些代码,将出现一个新窗口,其中有一个箭头形“海龟”不断地移动,并在身后留下移动轨迹。要将铅笔抬起,可使用penup();要将铅笔重新放下,可使用pendown()。要了解其他的命令,请参阅“Python库参考手册”的相关部分(https://docs.python.org/3/library/turtle.html)。要了解如何绘图,可尝试在网上搜索海龟绘图法(turtle graphic)。学习更多的概念后,你可能想用海龟绘图法替换平淡的print语句。在尝试使用海龟绘图法的过程中,你很快就会发现需要使用后面将介绍的一些基本编程结构。例如,如何在前面的示例中避免反复调用命令forward和left,如何绘制八角形(而不是三角形)以及如何以尽可能少的代码绘制多个边数各不相同的正多边形。1.9.1 从命令提示符运行Python脚本

实际上,运行程序的方式有多种。首先,假定你打开了DOS窗口或UNIX shell,并切换到了Python可执行文件(在Windows中为python.exe,在UNIX中为python)或将该可执行文件所在的目录加入6到了环境变量PATH中(仅适用于Windows)。另外,假定前一节的脚本(hello.py)存储在当前目录下。满足上述条件后,就可在Windows中使用如下命令来执行这个脚本:6如果你看不懂这句话,可以跳过1.9.1节,因为这一节的内容不是非得掌握的。C:\>python hello.py

在UNIX系统中,可使用如下命令:$ python hello.py

如你所见,命令是一样的,只是系统提示符不同。1.9.2 让脚本像普通程序一样

在有些情况下,你希望能够像执行其他程序(如Web浏览器或文本编辑器)一样执行Python脚本,而无需显式地使用Python解释器。UNIX提供了实现这种目标的标准方式:让脚本的第一行以字符序列#!(称为pound bang或shebang)开始,并在它后面指定用于对脚本进行解释的程序(这里是Python)的绝对路径。即便你对这一点不太明白,只需将下面的代码作为脚本的第一行,就可在UNIX中轻松运行脚本:#!/usr/bin/env python

不管Python库位于什么地方,这都将让你能够像运行普通程序一样运行脚本。如果你安装了多个版本的Python,可用更具体的可执行文件名(如python3)替换python。

要像普通程序一样运行脚本,还必须将其变成可执行的:$ chmod a+x hello.py

现在,可以像下面这样来运行它(假定当前目录包含在执行路径中):$ hello.py

如果这不管用,请尝试使用./hello.py,这在当前目录(.)未包含在执行路径中时也管用(负责的系统管理员会告诉你执行路径是什么)。

如果你愿意,可对文件进行重命名并删除扩展名.py,使其看起来更像普通程序。

如果双击会如何呢

在Windows中,扩展名.py是让脚本像普通程序一样的关键所在。请尝试双击前一节保存的文件hello.py。如果正确地安装了Python,这将打开一个DOS窗口,其中包含提示信息What is your 7name?。然而,这样运行程序存在一个问题:输入名字后,程序窗口将立即关闭,你根本来不及看清结果。这是因为程序结束后窗口将立即关闭。尝试修改脚本,在末尾添加如下代码行:7是否会这样取决于你使用的操作系统以及安装的Python解释器。例如,在macOS中,如果文件是使用IDLE存储的,双击文件将只会在IDLE代码编辑器中打开它。input("Press ")

现在运行这个程序并输入名字后,DOS窗口将包含如下内容:What is your name? GumbyHello, Gumby!Press

等你按回车键后,窗口将立即关闭,因为程序结束了。1.9.3 注释

在Python中,井号(#)比较特殊:在代码中,井号后面到行尾的所有内容都将被忽略。(这也是Python解释器未被前面的/usr/bin/env卡住的原因所在。)下面是一个示例:# 打印圆的周长:print(2 * pi * radius)

第一行为注释。注释让程序更容易理解:对其他人来说如此,在程序编写者回过头来阅读代码时亦如此。据说程序员应遵守的首要戒律是“汝应注释”,但是一些不那么宽容的程序员的座右铭是“如果写起来难,理解起来必然也难”。注释务必言而有物,不要重复去讲通过代码很容易获得的信息。无用而重复的注释还不如没有。例如,下述代码中的注释根本就是多余:# 获取用户的名字:user_name = input("What is your name?")

在任何情况下,都应确保代码即便没有注释也易于理解。所幸Python是一种卓越的语言,能让人很容易编写出易于理解的程序。1.10 字符串

前一节的代码"Hello, " + name + "!"是什么意思呢?本章的第一个程序只包含如下代码:print("Hello, world!")

编程教程通常以类似的程序开篇,问题是我还未全面阐述其工作原理。你已掌握了print语句的基本知识(后面将更详细地介绍它),但"Hello, world!"是什么呢?这是一个字符串(string)。几乎所有真实的Python程序中都有字符串的身影。字符串用途众多,但主要用途是表示一段文本,如感叹句“Hello, world!”。1.10.1 单引号字符串以及对引号转义

与数一样,字符串也是值:>>> "Hello, world!"'Hello, world!'

在这个示例中,有一点可能让你颇感意外:Python在打印字符串时,用单引号将其括起,而我们使用的是双引号。这有什么差别吗?其实没有任何差别。>>> 'Hello, world!''Hello, world!'

这里使用的是单引号,结果却完全相同。既然如此,为何同时支持单引号和双引号呢?因为在有些情况下,这可能会有用。>>> "Let's go!""Let's go!">>> '"Hello, world!" she said''"Hello, world!" she said'

在上述代码中,第一个字符串包含一个单引号(就这里而言,可能称之为撇号更合适),因此不能用单引号将整个字符串括起,否则解释器将报错(做出这样的反应是正确的)。>>> 'Let's go!'SyntaxError: invalid syntax

在这里,字符串为'Let',因此Python不知道如何处理后面的s(更准确地说是当前行余下的内容)。

第二个字符串包含双引号,因此必须使用单引号将整个字符串括起,原因和前面一样。实际上,并非必须这样做(这样做只是出于方便考虑)。可使用反斜杠(\)对引号进行转义,如下所示:>>> 'Let\'s go!'"Let's go!"

这样Python将明白中间的引号是字符串的一部分,而不是字符串结束的标志。虽然如此,Python打印这个字符串时,还是使用了双引号将其括起。与你预期的一样,对于双引号可采用同样的处理手法。>>> "\"Hello, world!\" she said"'"Hello, world!" she said'

像这样对引号进行转义很有用,且在有些情况下必须这样做。例如,在字符串同时包含单引号和双引号(如'Let\'s say "Hello, world!"')时,如果不使用反斜杠进行转义,该如何办呢?注意 厌烦了反斜杠?你在本章后面将看到,在大多数情况下,可通过使用长字符串和原始字符串(可结合使用这两种字符串)来避免使用反斜杠。1.10.2 拼接字符串

为处理前述不太正常的示例,来看另一种表示这个字符串的方式:>>> "Let's say " '"Hello, world!"''Let\'s say "Hello, world!"'

我依次输入了两个字符串,而Python自动将它们拼接起来了(合并为一个字符串)。这种机制用得不多,但有时候很有用。然而,仅当你同时依次输入两个字符串时,这种机制才管用。>>> x = "Hello, ">>> y = "world!">>> x ySyntaxError: invalid syntax

换而言之,这是一种输入字符串的特殊方式,而非通用的字符串拼接方法。那么应该如何拼接字符串呢?就像将数相加一样,将它们相加:>>> "Hello, " + "world!"'Hello, world!'>>> x = "Hello, ">>> y = "world!">>> x + y'Hello, world!'1.10.3 字符串表示str和repr

Python打印所有的字符串时,都用引号将其括起。你可能通过前面的示例发现了这一点。这是因为Python打印值时,保留其在代码中的样子,而不是你希望用户看到的样子。但如果你使用print,结果将不同。>>> "Hello, world!"'Hello, world!'>>> print("Hello, world!")Hello, world!

如果再加上表示换行符的编码\n,差别将更明显。>>> "Hello,\nworld!"'Hello,\nworld!'>>> print("Hello,\nworld!")Hello,world!

通过两种不同的机制将值转换成了字符串。你可通过使用函数8str和repr直接使用这两种机制。使用str能以合理的方式将值转换为用户能够看懂的字符串。例如,尽可能将特殊字符编码转换为相应的字符。然而,使用repr时,通常会获得值的合法Python表达式表示。8实际上,像int一样,str也是一个类,但repr是一个函数。>>> print(repr("Hello,\nworld!"))'Hello,\nworld!'>>> print(str("Hello,\nworld!"))Hello,world!1.10.4 长字符串、原始字符串和字节

有一些独特而有用的字符串表示方式。例如,有一种独特的语法可用于表示包含换行符或反斜杠的字符串(长字符串和原始字符串)。对于包含特殊符号的字符串,Python 2还提供了一种专用的表示语法,结果为Unicode字符串。这种语法现在依然管用,但是多余,因为在Python 3中,所有的字符串都是Unicode字符串。Python 3还引入了一种新语法,用于表示大致相当于老式字符串的字节对象。你将看到,在处理Unicode编码方面,这种对象依然扮演着重要的角色。01. 长字符串要表示很长的字符串(跨越多行的字符串),可使用三引号(而不是普通引号)。print('''This is a very long string. It continues here.And it's not over yet. "Hello, world!"Still here.''')还可使用三个双引号,如"""like this"""。请注意,这让解释

器能够识别表示字符串开始和结束位置的引号,因此字符串本身

可包含单引号和双引号,无需使用反斜杠进行转义。提示 常规字符串也可横跨多行。只要在行尾加上反斜杠,反斜杠和换行符将被转义,即被忽略。例如,如果编写如下代码:print("Hello, \ world!")它将打印Hello, world!。这种处理手法也适用于表达式和语句。>>> 1 + 2 + \ 4 + 512>>> print \ ('Hello, world')Hello, world02. 原始字符串原始字符串不以特殊方式处理反斜杠,因此在有些情况下很9

有用。在常规字符串中,反斜杠扮演着特殊角色:它对字符进

行转义,让你能够在字符串中包含原本无法包含的字符。例如,

你已经看到可使用\n表示换行符,从而像下面这样在字符串中包

含换行符:>>> print('Hello,\nworld!')Hello,world!这通常挺好,但在有些情况下,并非你想要的结果。如果你

要在字符串中包含\n呢?例如,你可能要在字符串中包含DOS路

径C:\nowhere。>>> path = 'C:\nowhere'>>> path'C:\nowhere'这好像没问题,但如果将其打印出来,就会出现问题。>>> print(path)C:owhere这并非你想要的结果,不是吗?那该怎么办呢?可对反斜杠

本身进行转义。>>> print('C:\\nowhere')C:\nowhere这很好,但对于很长的路径,将需要使用大量的反斜杠。path = 'C:\\Program Files\\fnord\\foo\\bar\\baz\\frozz\\bozz'在这样的情况下,原始字符串可派上用场,因为它们根本不

会对反斜杠做特殊处理,而是让字符串包含的每个字符都保持原

样。>>> print(r'C:\nowhere')C:\nowhere>>> print(r'C:\Program Files\fnord\foo\bar\baz\frozz\bozz')C:\Program Files\fnord\foo\bar\baz\frozz\bozz如你所见,原始字符串用前缀r表示。看起来可在原始字符

串中包含任何字符,这大致是正确的。一个例外是,引号需要像

通常那样进行转义,但这意味着用于执行转义的反斜杠也将包含

在最终的字符串中。>>> print(r'Let\'s go!')Let\'s go!另外,原始字符串不能以单个反斜杠结尾。换而言之,原始

字符串的最后一个字符不能是反斜杠,除非你对其进行转义(但

进行转义时,用于转义的反斜杠也将是字符串的一部分)。根据

前一个示例,这一点应该是显而易见的。如果最后一个字符(位

于结束引号前面的那个字符)为反斜杠,且未对其进行转义,

Python将无法判断字符串是否到此结束。>>> print(r"This is illegal\")SyntaxError: EOL while scanning string literal这合乎情理,但如果要指定以反斜杠结尾的原始字符串(如

以反斜杠结尾的DOS路径),该如何办呢?本节介绍了大量技巧,

应该能够帮助你解决这个问题,但基本技巧是将反斜杠单独作为

一个字符串,下面是一个简单的示例:>>> print(r'C:\Program Files\foo\bar' '\\')C:\Program Files\foo\bar\请注意,指定原始字符串时,可使用单引号或双引号将其括

起,还可使用三引号将其括起。03. Unicode、bytes和bytearrayPython字符串使用Unicode编码来表示文本。对大多数简单

程序来说,这一点是完全透明的,因此如果你愿意,可跳过本节,

等需要时再学习这个主题。然而,鉴于处理字符串和文本文件的

Python代码很多,大致浏览一下本节至少不会有什么坏处。大致而言,每个Unicode字符都用一个码点(code point)表

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

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载