书名:抢读版-Python编程快速上手(第2版)
ISBN:978-7-115-55187-0
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
著 [美] Al Sweigart
译 王海鹏
责任编辑 武晓燕
人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
读者服务热线:(010)81055410
反盗版热线:(010)81055315
Simplified Chinese-language edition copyright © 2020 by Posts and Telecom Press.
Copyright © 2019 by Al Sweigart.Title of English-language original: Automate The Boring Stuff with Python,2nd Edition ISBN-13: 978-1-59327-992-9, published by No Starch Press.
All rights reserved.
本书中文简体字版由美国No Starch出版社授权人民邮电出版社出版。未经出版者书面许可,对本书任何部分不得以任何方式复制或抄袭。
版权所有,侵权必究。
本书是一本面向初学者的 Python 编程实用指南。本书不仅介绍了 Python 语言的基础知识,而且通过案例实践教读者如何使用这些知识和技能。本书的第一部分介绍了基本的 Python 编程概念,第二部分介绍了一些不同的任务,通过编写Python程序,可以让计算机自动完成它们。第二部分的每一章都有一些项目程序供读者学习。每章的末尾还提供了一些习题和深入的实践项目,帮助读者巩固所学的知识。附录部分提供了所有习题的解答。
本书适合任何想要通过 Python 学习编程的读者,尤其适合缺乏编程基础的初学者。通过阅读本书,读者将能利用非常强大的编程语言和工具,并且体会到用 Python编程的快乐。
阿尔·斯维加特(Al Sweigart)是一名软件开发者和技术图书作者。Python 是他最喜欢的编程语言,他为 Python 开发了几个开源模块。他的其他著作都在他的网站上,以 Creative Commons 许可证的方式免费提供。
菲利普·詹姆斯(Philip James)在 Python 领域工作了 10 多年,经常在 Python社区发表演讲。他的演讲主题覆盖了从UNIX基础到开源社交网络。菲利普是BeeWare项目的核心贡献者,与他的搭档尼克(Nic)一起住在旧金山湾区。
在封面上只写上我的名字是一种误导。没有很多人的帮助,我不可能写出这样一本书。我想感谢我的出版人比尔·波洛克(Bill Pollock),我的编辑劳蕾尔·陈(Laurel Chun)、莱斯利·沈(Leslie Shen)、格雷格·普洛斯(Greg Poulos)、詹姆弗·格里菲斯-德尔加多(Jennifer Griffith-Delgado)和弗朗西斯·索克斯(Frances Saux),以及 No Starch Press 的其他工作人员,感谢他们非常宝贵的帮助。感谢我的技术评审奥里·拉森思基(Ari Lacenski)和菲利普·詹姆斯(Philip James),他们提供了极好的建议、编辑和支持。
非常感谢 Python 软件基金会的每个人,感谢他们了不起的工作。Python 社区是我在业界看到的最佳社区。
最后,我要感谢我的家人和朋友,以及在 Shotwell 的伙伴,他们不介意我在写这本书时非常忙碌的状态。
“你在两小时里完成的事,我们3个人要做两天。”21世纪早期,我的大学室友在一个电子产品零售商店工作。商店偶尔会处理一份电子表格,其中包含来自其他商店的数千种产品的价格。由3个员工组成的团队,会将这份电子表格打印在一叠厚厚的纸上,然后3个人分别处理一部分。针对每种产品,他们会查看自己商店的价格,并找出竞争对手们售价更低的所有产品。这通常会花几天的时间。
“如果你有打印件的原始文件,我会写一个程序来做这件事。”我的室友告诉他们,当时他看到他们坐在地板上,周围都是散落、堆叠的纸张。
几小时后,他写了一个简短的程序,从文件中读取竞争对手的价格,在商店的数据库中找到相应产品,并记录竞争对手的价格是否更便宜。他当时还是编程新手,花了许多时间在一本编程书中查看文档。实际上程序运行只花了几秒时间。我的室友和他的同事们那天享受了超长的午餐时间。
这就是计算机编程的威力。计算机就像瑞士军刀,可以用来完成数不清的任务。许多人花上数小时点击鼠标和敲打键盘,执行重复的任务,却没有意识到,如果他们给机器正确的指令,机器就能在几秒内完成他们的工作。
软件是我们今天使用的许多工具的核心:几乎每个人使用社交网络进行交流,许多人都有连接因特网的计算机,大多数办公室工作需要操作计算机来完成。因此,现在社会对编程人才的需求暴涨。无数的图书、交互式网络教程和开发者新兵训练营承诺将有雄心壮志的初学者变成软件工程师,让他们获得6位数的薪水。
本书不是针对这些人的,而是针对所有其他的人。
就本书来说,它不会让你变成一个职业软件开发者,就像学习几节吉他课程不会让你变成一名摇滚明星一样。但如果你是办公室职员、管理者、学术研究者,或其他任何使用计算机来工作或娱乐的人,通过本书,你将学到编程的基本知识,这样就能将下面这些简单的任务自动化。
对人来说,这些任务简单,但很花时间。它们通常很琐碎、很特殊,没有现成的软件可以完成。但是,拥有一点编程知识,就可以让计算机为你完成这些任务。
本书没有设计成参考手册,它是初学者指南。编程风格有时候违反最佳实践(例如有些程序使用全局变量),但这是一种折中方式,让代码更简单,以便学习。本书的目的是让人们编写用完即抛弃的代码,所以不用花太多时间来关注风格和优雅。复杂的编程概念(如面向对象编程、列表推导和生成器)在本书中也没有出现,因为它们增加了复杂性。编程老手可能会指出,本书中的代码可以修改得更有效率,但本书主要考虑的是用最少的工作量得到能工作的程序。
在电视剧和电影中,我们常常看到程序员在闪光的屏幕前迅速地输入密码般的一串1和0,但现代编程没有这么神秘。“编程”就是输入指令让计算机来执行。这些指令可能用于运算一些数字、修改文本、在文件中查找信息,或通过因特网与其他计算机通信。
所有程序都使用基本指令作为构件块。下面是一些常用的指令,用自然语言的形式来表示。
也可以组合这些构件块,以实现更复杂的功能。例如,下列所示的是一些编程指令,称为“源代码”,是用Python编程语言编写的一个简单程序。Python软件从头开始执行每行代码(有些代码只有在特定条件为真时才执行,为假时Python会执行另外一些代码),直到代码结束。
❶ passwordFile = open('SecretPasswordFile.txt')
❷ secretPassword = passwordFile.read()
❸ print('Enter your password.')
typedPassword = input()
if typedPassword == secretPassword:
❺ print('Access granted')
❻ if typedPassword == '12345':
❼ print('That password is one that an idiot puts on their luggage.')
else:
❽ print('Access denied')
你可能对编程一无所知,但读了上面的代码,也许就能够合理地猜测它做的事了。首先,打开了文件SecretPasswordFile.txt❶,读取了其中的口令❷。然后,提示用户(通过键盘)输入一个口令❸。比较这两个口令,如果它们一样,程序就在屏幕上输出Access granted❺。接下来,程序检查口令是否为12345❻,提示说这可能并不是最好的口令❼。如果口令不一样,程序就在屏幕上输出Access denied❽。
Python指的是Python编程语言(包括语法规则,用于编写被认为是有效的Python代码);也指Python解释器软件,它读取源代码(用Python语言编写),并执行其中的指令。Python解释器可以从Python的官方网站免费下载,有针对Linux操作系统、macOS和Windows操作系统的版本。
Python的名字来自超现实主义的英国喜剧团体,而不是来自蛇。Python程序员被亲切地称为Pythonistas。Monty Python和与蛇相关的引用常常出现在Python的指南和文档中。
我听到的关于学习编程的最常见的顾虑,就是人们认为这需要很多数学知识。其实,大多数编程需要的数学知识不超过基本算数。实际上,善于编程与善于解决数独问题没有太大差别。
要解决数独问题,数字1~9必须填入9×9棋盘的每一行、每一列,以及每个3×3的内部方块。系统提供了一些数字来帮助你开始,然后你可以根据这些数字进行推算,从而找到答案。例如,在图 0-1的数独问题中,既然5出现在了第1行和第2行,它就不能在这些行中再次出现。因此,在右上角的网格中,它必定在第3行;由于最后一列已有了5,5就不能在6的右边。每次解决一行、一列或一个方块,将为剩下的部分提供更多的数字线索。随着你填入一组数字1~9,然后再填写另一组数字,整个网格很快就会被填满。
图0-1 一个新的数独问题(左边)及其答案(右边)。尽管使用了数字,
但数独并不需要太多数学知识
数独虽然使用了数字,但并不意味着必须精通数学才能求出答案。编程也是这样。就像解决数独问题一样,编程需要将一个问题分解为单个的、详细的步骤。类似地,在“调试”程序(即寻找和修复错误)时,你会耐心地观察程序在做什么,找出出现错误的原因。像所有技能一样,编程越多,你就掌握得越好。
我听到的关于编程的第二常见的焦虑是,认为自己太老了,无法学习编程。我见到许多人在网上发表了评论,他们认为对自己来说为时已晚,因为他们已经23岁了。显然,这并不是因太“老”而无法学习编程:许多人在晚年生活中也能学到很多东西。
要成为一名有能力的程序员,你不需要从小就开始。但是,程序员像神童一般的形象反复出现。不幸的是,当我告诉别人我从读小学就开始编程时,我也为这个神话做出了贡献。
但是,如今的编程比20世纪90年代更容易学习。今天,有更多的书籍、更好的搜索引擎以及更多的在线问答网站。最重要的是,编程语言本身更加易于使用。由于这些原因,现在大约用12个周末,就可以了解我从小学到高中毕业学到的编程知识。我领先得并不是太多。
对编程抱有“成长心态”很重要,换言之,要明白人们是通过实践来培养编程技能的。他们不是生来就是程序员,现在不具备编程技能,并不表示你永远无法成为专家。
编程是一项创造性活动,就像绘画、写作、编织或用积木构建一个城堡。就像在一张空白画布上绘画,制作软件虽然有许多限制,但有无限的可能。
编程与其他创造性活动的不同之处在于,在编程时,你需要的所有原材料都在计算机中,你不需要购买额外的画布、颜料、胶片、纱线、积木或电子器件等。一台10年前的老旧计算机,对于编写程序来说已经足够强大,绰绰有余。在程序写好后,它可以被完美地复制无数次。编织的毛衣一次只能给一个人穿,但有用的程序很容易在线分享给整个世界。
本书的第一部分介绍Python的基本编程概念;第二部分介绍一些不同的任务,你可以让计算机自动完成它们。第二部分的每一章都有一些项目程序,供你学习。下面简单介绍一下每章的内容。
第一部分:Python编程基础
“第 1 章 Python基础”介绍表达式、Python指令的最基本类型,以及如何使用Python交互式环境来尝试运行代码。
“第 2 章 控制流”解释如何让程序决定执行哪些指令,以便代码能够智能地响应不同的情况。
“第 3 章 函数”介绍如何定义自己的函数,以便将代码组织成可管理的部分。
“第4章 列表”介绍列表数据类型,解释如何组织数据。
“第 5 章 字典和结构化数据”介绍字典数据类型,展示更强大的数据组织方法。
“第6章 字符串操作”介绍处理文本数据(在Python中称为“字符串”)的方法。
第二部分:自动化任务
“第7章 模式匹配与正则表达式”介绍Python如何用正则表达式处理字符串,以及查找文本模式。
“第 8 章 输入验证”解释程序如何验证用户提供的信息,确保用户数据到达时的格式不会在程序的其余部分中引起错误。
“第 9 章 读写文件”解释程序如何读取文本文件的内容,并将信息保存到硬盘的文件中。
“第10 章 组织文件”将展示Python如何用比手动操作快得多的速度复制、移动、重命名和删除大量的文件,也将解释如何用Python压缩和解压缩文件。
“第11章 调试”展示如何使用Python的缺陷查找和缺陷修复工具。
“第 12 章 从Web抓取信息”展示如何通过编程来自动下载网页,并解析它们,获取信息。
“第 13 章 处理Excel电子表格”介绍通过编程处理Excel电子表格的方法。如果你分析的文档很少,这样你就不必去阅读它们。如果你必须分析成百上千的文档,这章知识是很有帮助的。
“第14章 处理Google电子表格”介绍通过如何使用Python读取和更新Google表格(一种流行的基于Web的电子表格应用程序)。
“第15章 处理PDF和Word文档”介绍编程处理PDF和Word文档的方法。
“第16章 处理 CSV 文件和 JSON 数据”解释如何编程处理 CSV 文件和JSON数据。
“第17章 保持时间、计划任务和启动程序”解释Python程序如何处理时间和日期,如何安排计算机在特定时间执行任务。这一章也将展示Python程序如何启动非Python程序。
“第18章 发送电子邮件和短信”解释如何通过编程来发送电子邮件和短信。
“第19章 操作图像”解释如何通过编程来操作JPG或PNG等格式的图像。
“第20章 用GUI自动化控制键盘和鼠标”解释如何通过编程控制鼠标和键盘,自动化鼠标点击和按键。
“附录A 安装第三方模块”展示如何利用有用的附加模块来扩展Python。
“附录B 运行程序”展示如何在代码编辑器之外,在Windows操作系统、macOS和UbuntuLinux操作系统上运行Python程序。
“附录C 习题答案”提供每章末尾习题的答案,以及一些其他背景知识。
可以从Python的官方网站免费下载针对Windows操作系统、macOS和UbuntuLinux操作系统的Python版本。如果你从该网站的下载页面下载了最新的版本,那么本书中的所有程序应该都能工作。
警告:请确保下载Python 3的版本(如3.8.0)。本书中的程序将运行在Python 3上,有一部分程序在Python 2上也许不能正常运行。
你需要在下载页面上找到针对64位或32位计算机以及特定操作系统的Python安装程序,所以先要弄清楚你需要哪个安装程序。如果你的计算机是2007年及以后购买的,很有可能是64位的系统;否则,可能是32位的系统,下面是确认的方法。
uname -m
。结果是i686表示32位,x86_64表示64位。在Windows操作系统上,下载Python安装程序(文件扩展名是.msi),并双击它。按照安装程序显示在屏幕上的指令来安装Python,步骤如下。
1.选择Install for All Users,然后单击Next。
2.在接下来的几个窗口中,依次单击Next,接受默认选项。
在macOS上,下载适合你的macOS版本的.dmg文件,并双击它。按照安装程序显示在屏幕上的指令来安装Python,步骤如下。
1.当DMG包在一个新窗口中打开时,双击Python.mpkg文件。你可能必须输入管理员口令。
2.单击Continue,跳过欢迎部分,并单击Agree,接受许可证。
3.在最后的窗口中,单击Install。
如果使用的是Ubuntu Linux操作系统,可以从命令行窗口安装Python,步骤如下。
1.打开命令行窗口。
2.输入sudo apt-get install python3
。
3.输入sudo apt-get install idle3
。
4.输入sudo apt-get install python3-pip
。
“Python解释器”是运行Python程序的软件,而“Mu编辑器软件”则是你输入程序的地方,这与你在文字处理器中输入内容的方式非常相似。
在Windows操作系统和macOS上下载适合你的操作系统的安装程序,然后通过双击安装程序文件来运行它。如果你使用的是macOS,那么运行安装程序时会打开一个窗口,你必须在其中将Mu图标拖动到Applications文件夹中才能继续安装。如果你使用的是UbuntuLinux操作系统,那么需要将Mu安装为Python软件包。在这种情况下,请单击下载页面“Python Package”部分中的Instructions按钮。
安装完成后,让我们启动Mu
。
–m mu
。第一次运行Mu时,屏幕将显示一个“Select Mode”(选择模式)窗口,其中包含选项Adafruit CircuitPython、BBC micro:bit、Pygame Zero和Python3。选择Python3。以后,你就可以通过单击编辑器窗口顶部的Mode按钮来更改模式了。
注意:你需要下载Mu 1.10.0版本或更高版本,这样才能安装本书介绍的第三方模块。在编写本书时,Mu 1.10.0是一个Alpha版本,在下载页面上作为单独链接列出,与主要下载链接分开。
本书使用Mu作为编辑器和交互式环境。但是,你可以使用各种编辑器来编写Python代码。“集成开发和学习环境”(IDLE)软件与Python一起安装,如果出于某种原因,你不能安装Mu或让它工作,IDLE可以作为另一个编辑器。现在让我们启动IDLE。
IDLE
,并选择IDLE(Python GUI)。idle3
(你也可以单击屏幕顶部的Applications,选择Programming,然后单击IDLE 3)。运行Mu时,出现的窗口称为“文件编辑器”窗口。你可以通过单击REPL按钮打开“交互式环境”。该环境是一个程序,可以让你在计算机中输入指令,就像在macOS和Windows操作系统上各自的“终端”或“命令提示符”中输入一样。使用Python的交互式环境,你可以输入指令,让Python解释器软件运行它们。计算机将读取你输入的指令并立即运行它们。
在Mu中,交互式环境是窗口下半部分的窗格,其中包含以下文本:
Jupyter QtConsole 4.3.1
Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit
(AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help. In[1]:
如果运行IDLE,则交互式环境是第一个出现的窗口。除了看起来像下面这样的文本外,大部分应该为空白:
Python 3.8.0b1 (tags/v3.8.0b1:3b5deb0116, Jun 4 2019, 19:52:55) [MSC v.1916
64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
In [1]
:和>>>称为“提示符”。本书中的示例将用>>>提示符表示交互式环境,因为它更常见。如果你在命令行窗口中运行Python,它们也会使用>>>提示符。In [1]
:提示符是另一种流行的Python编辑器——Jupyter Notebook发明的。
例如,在交互式环境的提示符后输入以下指令:
>>> print('Hello, world!')
在输入该行并按下回车键后,交互式环境将显示以下内容作为响应:
>>> print('Hello, world!')
Hello, world!
你刚刚给计算机提供了一条指令,它完成了你要执行的操作。
一些Python代码要求你的程序导入模块。其中一些模块是Python附带的,而有些模块是Python核心开发团队之外的开发人员创建的第三方模块。附录A详细说明了如何使用pip程序(在Windows操作系统上)或pip3程序(在macOS和Linux操作系统上)安装第三方模块。当本书要求你安装特定的第三方模块时,请查阅附录A。
程序员喜欢通过在因特网上搜索问题的答案来学习。这不同于许多人习惯的学习方式,即通过一名亲自授课并可以回答问题的老师来进行学习。使用因特网作为教师的最大好处是,整个社区的人都可以回答你的问题。
实际上,你的问题可能已经有人回答了,答案已经在线,等待你找到它们。许多人都会遇到错误信息或代码无法正常工作的情况,你不会是第一个遇到这个问题的人,找到解决方案比你想象的要容易。
例如,让我们故意制造一个错误:在交互式环境中输入'42' + 3。你现在不需要了解这条指令的含义,但结果应如下所示:
>>> '42' + 3
❶ Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
'42' + 3
❷ TypeError: Can't convert 'int' object to str implicitly
>>>
这里出现了错误信息❷,因为Python不理解你的指令。错误信息的Traceback部分❶显示了Python遇到困难的特定指令和行号。如果你不知道怎样处理特定的错误信息,就在线查找那条错误信息。在你喜欢的搜索引擎上输入“TypeError: Can't convert 'int' object to str implicitly
”(包括单引号),你就会看到许多的链接解释了这条错误信息的含义,以及什么原因导致这个错误,如图0-2所示。
图0-2 错误信息的搜索结果
你常常会发现,别人也遇到了同样的问题,而其他乐于助人的人已经回答了这个问题。没有人知道编程的所有知识,因此所有软件开发者的日常工作之一都是在寻找技术问题的答案。
如果不能在线查找到答案,请尝试在Stack Overlow或Reddit子板块“learn programming”这样的论坛上提问。但要记住用聪明的方式提出编程问题,这有助于别人来帮助你。确保阅读这些网站的FAQ(常见问题),了解正确的提问方式。
在提出编程问题时,要记住以下几点。
对于大多数人,他们的计算机只是设备,而不是工具。但通过学习编程,你就能利用现代社会中强大的工具,并且你会一直感到快乐。编程不是脑外科手术,业余人士是完全可以尝试和犯错的。
本书假定你编程的知识为零,并且会教给你很多知识,但你的问题可能超出本书的范围。记住如何有效地提问,如何寻找答案,这对于你的编程之旅是无价的。
本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。
本书提供如下资源:
本书源代码;
书中彩图文件。
要获得以上配套资源,请在异步社区本书页面中单击,跳转到下载界面,按提示进行操作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。
虽然作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。
当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,单击“提交勘误”,输入勘误信息,单击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。
我们的联系邮箱是contact@epubit.com.cn。
如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。
如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线投稿(直接访问www.epubit.com/ selfpublish/submission即可)。
如果您所在的学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。
如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。
“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。
“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。
异步社区
微信服务号
本篇内容
第1章 Python基础
第2章 控制流
第3章 函数
第4章 列表
第5章 字典和结构化数据
第6章 字符串操作
Python编程语言有许多语法结构、标准库函数和交互式开发环境功能。好在你可以忽略大多数内容,只需要学习部分内容,就能编写一些方便的小程序。
但在动手之前,你必须学习一些基本编程概念。就像魔法师培训,你可能认为这些概念既深奥又啰唆,但有了一些知识和实践,你就能像魔法师一样指挥你的计算机,完成难以置信的事情。
本章有几个例子,我们鼓励你在“交互式环境”中输入它们。交互式环境也称为“REPL(‘读取—求值—输出’循环)”。交互式环境让你每次运行(或“执行”)一条Python指令,并立即显示结果。使用交互式环境对于了解基本Python指令的行为是很好的,所以你在阅读时要试一下。做事比仅仅读内容更令人印象深刻。
可以通过启动Mu编辑器来运行交互式环境,你在阅读前言中的安装说明时应该已经下载了Mu编辑器。在Windows操作系统上,打开“开始”菜单,输入“Mu”,然后打开Mu应用程序。在macOS上,打开“应用程序”文件夹,然后双击Mu;单击New按钮,然后将一个空文件另存为blank.py;当你通过单击Run按钮或按F5键运行这个空白文件时,它将打开交互式环境,该环境将作为一个新窗格打开,该窗格在Mu编辑器窗口的底部打开。你应该可以在交互式环境中看到>>>提示符。
在提示符处输入2 + 2
,让Python做一些简单的数学运算。Mu窗口现在应如下所示:
>>> 2 + 2
4
>>>
在Python中,2 + 2称为“表达式”,它是语言中最基本的编程结构。表达式包含“值”(例如2)和“操作符”(例如+),并且总是可以“求值”(即归约)为单个值。这意味着在Python代码中,所有使用表达式的地方都可以使用一个值。
在前面的例子中,2 + 2
求值为单个值4。没有操作符的单个值也被认为是一个表达式,尽管它求值的结果就是它自己,像下面这样:
>>> 2
2
错误没关系
如果程序包含计算机不能理解的代码,就会崩溃,这将导致Python显示错误信息。错误信息并不会破坏你的计算机,所以不要害怕犯错误。“崩溃”只是意味着程序意外地停止执行。
如果你希望对一条错误信息了解更多,可以在网上查找这条错误信息的准确文本,找到关于这个错误的更多内容。也可以进入no starch出版社官网本书对应页面,那里有常见的Python错误信息和含义的列表。
Python表达式中也可以使用大量其他操作符。例如,表 1-1 列出了Python的所有数学操作符。
表1-1 Python数学操作符,优先级从高到低
操作符 |
操作 |
例子 |
求值为 |
---|---|---|---|
** |
指数 |
2 ** 3 |
8 |
% |
取模/取余数 |
22 % 8 |
6 |
// |
整除/商数取整 |
22 // 8 |
2 |
/ |
除法 |
22 / 8 |
2.75 |
* |
乘法 |
3 * 5 |
15 |
- |
减法 |
5 - 2 |
3 |
+ |
加法 |
2 + 2 |
4 |
Python数学操作符的“操作顺序”(也称为“优先级”)与数学中类似。**操作符首先求值;接下来是*、/、//和%操作符,从左到右;+和-操作符最后求值,也是从左到右。如果需要,可以用括号来改变通常的优先级。运算符和值之间的空格对于Python无关紧要(行首的缩进除外),但是惯例是保留一个空格。在交互式环境中输入下列表达式:
>>> 2 + 3 * 6
20
>>> (2 + 3) * 6
30
>>> 48565878 * 578453
28093077826734
>>> 2 ** 8
256
>>> 23 / 7
3.2857142857142856
>>> 23 // 7
3
>>> 23 % 7
2
>>> 2 + 2
4
>>> (5 - 1) * ((7 + 1) / (3 - 1))
16.0
在每个例子中,作为程序员,你必须输入表达式,由Python完成较难的工作,将它求值为单个值。Python将继续对表达式的各个部分进行求值,直到它成为单个值,如下所示。
将操作符和值放在一起构成表达式的这些规则,是 Python 编程语言的基本部分,就像帮助我们沟通的语法规则一样。下面是例子。
This is a grammatically correct English sentence.
This grammatically is sentence not English correct a.
第二行很难解释,因为它不符合自然语言的规则。类似地,如果你输入错误的 Python指令,Python也不能理解,就会显示出错误信息,像下面这样:
>>> 5 +
File "<stdin>", line 1
5 +
^
SyntaxError: invalid syntax
>>> 42 + 5 + * 2
File "<stdin>", line 1
42 + 5 + * 2
^
SyntaxError: invalid syntax
你总是可以在交互式环境中输入一条指令,检查它是否能工作。不要担心会弄坏计算机:最坏的情况就是Python显示错误信息。专业的软件开发者在编写代码时,常常会遇到错误信息。
记住,表达式是值和操作符的组合,它们可以通过求值成为单个值。“数据类型”是一类值,每个值都只属于一种数据类型。表1-2列出了Python中最常见的数据类型。例如,值-2和30属于“整型”值。整型(或int)表明值是整数。带有小数点的数,如3.14,称为“浮点型”(或float)。请注意,尽管42是一个整型,但42.0是一个浮点型。
表1-2 常见数据类型
数据类型 |
例子 |
---|---|
整型 |
−2、−1、0、1、2、3、4、5 |
浮点型 |
−1.25、−1.0、−0.5、0.0、0.5、1.0、1.25 |
字符串 |
'a'、'aa'、'aaa'、'Hello!'、'11 cats' |
Python程序也可以有文本值,称为“字符串”或strs(发音为“stirs”)。总是用单引号(')包围住字符串(例如'Hello'
或'Goodbye my friend!'
),这样Python就能判断字符串的开始和结束。甚至可以有没有字符的字符串,称为“空字符串”或“空串”。第6章将更详细地解释字符串。
如果出现错误信息SyntaxError: EOL while scanning string literal
,可能是忘了字符串末尾的单引号,如下面的例子所示:
>>> 'Hello world!
SyntaxError: EOL while scanning string literal
根据操作符之后的值的数据类型,操作符的含义可能会改变。例如,在操作两个整型或浮点型值时,+是相加操作符;但是,在用于两个字符串之间时,它将字符串连接起来,成为“字符串连接”操作符。在交互式环境中输入以下内容:
>>> 'Alice' + 'Bob'
'AliceBob'
该表达式求值为一个新字符串,包含了两个字符串的文本。但是,如果你对一个字符串和一个整型值使用+操作符,Python就不知道如何处理,它将显示一条错误信息:
>>> 'Alice' + 42
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
'Alice' + 42
TypeError: can only concatenate str (not "int") to str
错误信息Can only concatenate str(not "int")to str
表示Python认为你试图将一个整数连接到字符串'Alice'
。代码必须显式地将整数转换为字符串,因为Python不能自动完成转换。(1.6节“程序剖析”在讨论str()
、int()
和float()
函数时,将解释数据类型转换。)
*
操作符将两个整型或浮点型值相乘。但如果*
操作符用于一个字符串值和一个整型值,它就变成了“字符串复制”操作符。在交互式环境中输入一个字符串乘以一个数字,效果如下:
>>> 'Alice' * 5
'AliceAliceAliceAliceAlice'
该表达式求值为一个字符串,它将原来的字符串复制若干次,次数就是整型的值。字符串复制是一个有用的技巧,但不像字符串连接那样常用。
*
操作符只能用于两个数字(作为乘法),或一个字符串和一个整型值(作为“字符串复制”操作符)。否则,Python将显示错误信息,像下面这样:
>>> 'Alice' * 'Bob'
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
'Alice' * 'Bob'
TypeError: can't multiply sequence by non-int of type 'str'
>>> 'Alice' * 5.0
Traceback (most recent call last):
File "<pyshell#33>", line 1, in <module>
'Alice' * 5.0
TypeError: can't multiply sequence by non-int of type 'float'
Python不理解这些表达式是有道理的:你不能把两个单词相乘,也很难将一个任意字符串复制小数次。
“变量”就像计算机内存中的一个盒子,其中可以存放一个值。如果你的程序稍后将用到一个已求值的表达式的结果,就可以将它保存在一个变量中。
用“赋值语句”将值保存在变量中。赋值语句包含一个变量名、一个等号(称为“赋值操作符”),以及要存储的值。如果输入赋值语句spam = 42
,那么名为spam
的变量将保存一个整型值42。
可以将变量看成一个带标签的盒子,值放在其中,如图1-1所示。
例如,在交互式环境中输入以下内容:
❶ >>> spam = 40
>>> spam
40
>>> eggs = 2
❷ >>> spam + eggs
42
>>> spam + eggs + spam
82
❸ >>> spam = spam + 2
>>> spam
42
第一次存入一个值,变量就被“初始化”(或创建)❶。此后,可以在表达式中使用它,以及其他变量和值❷。如果变量被赋了一个新值,老值就被忘记了❸。这就是为什么在例子结束时,spam
求值为42,而不是40。这称为“覆写”该变量。在交互式环境中输入以下代码,尝试覆写一个字符串:
>>> spam = 'Hello'
>>> spam
'Hello'
>>> spam = 'Goodbye'
>>> spam
'Goodbye'
就像图1-2所示的盒子,这个例子中的spam
变量保存了'Hello'
,直到你用'Goodbye'
替代它。
图1-1 spam
= 42就像是告诉程序“变量spam
现在有整型值42放在里面”
图1-2 一个新值赋给变量,老值就被遗忘了
好的变量名描述了它包含的数据。设想你搬到一间新屋子,搬家纸箱上标的都是“东西”。这让你找不到任何东西。本书的例子和许多Python的文档使用spam
、eggs
和bacon
等变量名作为一般名称(受到Monty Python的“Spam”短剧的影响),但在你的程序中,使用描述性名字有助于提高代码可读性。
尽管你几乎可以为变量任意命名,但是Python确实有一些命名限制。表1-3中有一些有效的和无效的变量名的例子。你可以给变量取任何名字,只要它遵守以下3条规则。
表1-3 有效和无效的变量名
有效的变量名 |
无效的变量名 |
---|---|
current_balance |
current-balance(不允许短横线) |
currentBalance |
current balanc(不允许空格) |
account4 |
4account(不允许数字开头) |
_42 |
42(不允许数字开头) |
TOTAL_SUM |
TOTAL_$UM(不允许$这样的特殊字符) |
hello |
'hello'(不允许'这样的特殊字符) |
1.只能是一个词,不带空格。
2.只能包含字母、数字和下划线(_)字符。
3.不能以数字开头。
变量名是区分大小写的。这意味着,spam
、SPAM
、Spam
和sPaM
是4个不同的变量。尽管Spam
是一个有效的变量,你可以在程序中使用,但变量用小写字母开头是Python的惯例。
本书的变量名使用了“驼峰形式”,没有用下划线。也就是说,变量名用lookLikeThis
,而不是looking_like_this
。一些有经验的程序员可能会指出,官方的Python代码风格为PEP 8,即应该使用下划线。一致地满足风格指南是重要的。但最重要的是知道何时要不一致,因为有时候风格指南就是不适用。如果有怀疑,请相信自己的最佳判断。
虽然交互式环境一次运行一条Python指令很好,但要编写完整的Python程序,就需要在文件编辑器中输入指令。“文件编辑器”类似于Notepad或TextMate这样的文本编辑器,它有一些针对输入源代码的特殊功能。要在Mu中打开新文件,请单击顶部的New按钮。
出现的窗口中应该包含一个光标,等待你输入,但它与交互式环境不同。在交互式环境中,按回车键就会执行Python指令。文件编辑器允许输入多条指令,将指令保存为文件,并运行该文件。下面是区别这两者的方法。
现在创建第一个程序。打开文件编辑器窗口后,输入以下内容:
❶ # This program says hello and asks for my name.
❷ print('Hello, world!')
print('What is your name?') # ask for their name
❸ myName = input()
❹ print('It is good to meet you, ' + myName)
❺ print('The length of your name is:') print(len(myName))
❻ print('What is your age?') # ask for their age myAge = input()
print('You will be ' + str(int(myAge) + 1) + ' in a year.')
在输入完源代码后保存它,就不必在每次启动Mu时重新输入。单击Save按钮,在File Name字段后输入hello.py,然后单击Save按钮。
在输入程序时,应该过一段时间就保存你的程序。这样,如果计算机崩溃,或者不小心退出了Mu,也不会丢失代码。可以在Windows操作系统和Linux操作系统上按Ctrl-S快捷键,在macOS上按Command-S快捷键来保存文件。
在保存文件后,让我们来运行程序。按F5键,程序将在交互式环境窗口中运行。记住,必须在文件编辑器窗口中按F5键,而不是在交互式环境窗口中。在程序要求输入时,输入你的名字。在交互式环境中,程序输出应该看起来像下面这样:
Python 3.7.0b4 (v3.7.0b4:eb96c37699, May 2 2018, 19:02:22) [MSC v.1913 64 bit
(AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
Hello, world!
What is your name?
Al
It is good to meet you, Al The length of your name is: 2
What is your age?
4
You will be 5 in a year.
>>>
如果没有更多代码行要执行,Python程序就会“中止”。也就是说,它会停止运行。(也可以说Python程序“退出”了。)
可以通过单击窗口顶部的“关闭”按钮关闭文件编辑器。要重新加载一个保存了的程序,就在菜单中选择FileOpen。现在请这样做,在出现的窗口中选择hello.py,并单击Open按钮。前面保存的程序hello.py应该在文件编辑器窗口中打开。
你可以用Python Tutor网站的可视化工具来查看程序的执行情况。你可以在Python Tutor的可视化页面上看到这个程序的执行。单击前进按钮以浏览程序执行的每个步骤。你将能够看到变量值和输出如何变化。
新程序在文件编辑器中打开后,让我们快速看一看它用到的Python指令,逐一查看每行代码。
下面这行称为“注释”。
❶ # This program says hello and asks for my name.
Python会忽略注释,你可以用它们来解释说明程序,或提醒自己代码试图完成的事。这一行中,#标志之后的所有文本都是注释。
有时候,程序员在测试代码时,会在一行代码前面加上#,临时删除它这行代码。这称为“注释掉”代码。在你想搞清楚为什么程序不工作时,这样做可能有用。如果你准备还原这一行代码,可以去掉#。
Python也会忽略注释之后的空行。在程序中,想加入空行时就可以加入。这会让你的代码更容易阅读,就像书中的段落一样。
print()
函数将括号内的字符串输出在屏幕上:
❷ print('Hello, world!')
print('What is your name?') # ask for their name
代码行print('Hello, world!')
表示“输出字符串'Hello world!'
的文本”。Python执行到这行时,表示Python在“调用”print()
函数,并将该字符串的值“传递”给函数。传递给函数的值称为“参数”。请注意,引号没有输出在屏幕上,它们只是表示字符串的起止,不是字符串的一部分。
注意:也可以用这个函数在屏幕上输出空行,只要调用print()就可以了,括号内没有任何东西。
在写函数名时,末尾带上括号表明它是一个函数的名字。这就是为什么在本书中你会看到print()
,而不是print
。第3章将更详细地探讨函数。
input()
函数等待用户在键盘上输入一些文本,并按回车键:
❸ myName = input()
这个函数的字符串,即用户输入的文本。上面的代码行将这个字符串赋给变量myName
。
你可以认为input()
函数调用是一个表达式,它处理用户输入的任何字符串。如果用户输入'Al'
,那么该表达式的结果为myName = 'Al'
。
如果调用input()
并看到错误信息,例如NameError: name 'Al' is not defined
,那么问题是你使用的是Python 2,而不是Python 3。
接下来的print()
调用,实际上在括号中包含了表达式'It is good to meet you, ' + myName
:
❹ print('It is good to meet you, ' + myName)
要记住,表达式总是可以求值为一个值。如果'Al'
是上一行代码保存在myName
中的值,那么这个表达式就求值为'It is good to meet you, Al'
。这个字符串传给print()
,它将输出到屏幕上。
你可以向len()
函数传递一个字符串(或包含字符串的变量),然后该函数求值为一个整型值,即字符串中字符的个数:
❺ print('The length of your name is:')
print(len(myName))
在交互式环境中输入以下内容试一试:
>>> len('hello')
5
>>> len('My very energetic monster just scarfed nachos.')
46
>>> len('')
0
就像这些例子,len(myName)
求值为一个整数。然后它被传递给print()
,在屏幕上显示。请注意,print()
允许传入一个整型值或字符串。但如果在交互式环境中输入以下内容,就会报错:
>>> print('I am ' + 29 + ' years old.')
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
print('I am ' + 29 + ' years old.')
TypeError: Can't convert 'int' object to str implicitly
导致错误的不是print()
函数,而是你试图传递给print()
的表达式。如果在交互式环境中单独输入这个表达式,也会得到同样的错误:
>>> 'I am ' + 29 + ' years old.'
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
'I am ' + 29 + ' years old.'
TypeError: Can't convert 'int' object to str implicitly
报错是因为只能用+操作符加两个整数或连接两个字符串,不能让一个整数和一个字符串相加,因为这不符合Python的语法。可以使用字符串型的整数修复这个错误,这在下一小节中解释。
如果想要连接一个整数(如29
)和一个字符串,再传递给print()
,就需要获得值'29'
,它是29
的字符串形式。str()
函数可以传入一个整型值,并求值为它的字符串形式,像下面这样:
>>> str(29)
'29'
>>> print('I am ' + str(29) + ' years old.')
I am 29 years old.
因为str(29)
求值为'29
',所以表达式'I am ' + str(29) +' years old.'
求值为'I am ' + '29' + ' years old.'
,它又求值为'I am 29 years old.'
。这就是传递给print()
函数的值。
str()
、int()
和float()
函数将分别求值为传入值的字符串、整数和浮点数形式。请尝试用这些函数在交互式环境中转换一些值,看看会发生什么:
>>> str(0)
'0'
>>> str(-3.14)
'-3.14'
>>> int('42')
42
>>> int('-99')
-99
>>> int(1.25)
1
>>> int(1.99)
1
>>> float('3.14')
3.14
>>> float(10)
10.0
前面的例子调用了str()
、int()
和float()
函数,向它们传入其他数据类型的值,得到了字符串、整型或浮点型的值。
如果想要将一个整数或浮点数与一个字符串连接,用str()
函数就很方便。如果你有一些字符串值,希望将它们用于数学运算,int()
函数也很有用。例如,input()
函数总是返回一个字符串,即便用户输入的是一个数字。在交互式环境中输入spam = input()
,在它等待文本时输入101
:
>>> spam = input()
101
>>> spam
'101'
保存在spam
中的值不是整数101
,而是字符串'101'
。如果想要用spam
中的值进行数学运算,那就用int()
函数取得spam
的整数形式,然后将这个新值存在spam
中:
>>> spam = int(spam)
>>> spam
101
现在你应该能将spam
变量作为整数使用,而不是作为字符串使用:
>>> spam * 10 / 5
202.0
请注意,如果你将一个不能求值为整数的值传递给int()
,Python将显示错误信息:
>>> int('99.99')
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
int('99.99')
ValueError: invalid literal for int() with base 10: '99.99'
>>> int('twelve')
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
int('twelve')
ValueError: invalid literal for int() with base 10: 'twelve'
如果需要对浮点数进行取整运算,也可以用int()
函数:
>>> int(7.7)
7
>>> int(7.7) + 1
8
在你的程序中,最后3行使用了函数int()
和str()
,以取得适当数据类型的值:
❻ print('What is your age?') # ask for their age
myAge = input()
print('You will be ' + str(int(myAge) + 1) + ' in a year.')
文本和数字相等判断
虽然数字的字符串值被认为与整型值和浮点型值完全不同,但整型值可以与浮点型值相等:
>>> 42 == '42'
False
>> 42 == 42.0
True
>> 42.0 == 0042.000
True
Python进行这种区分,主要是因为字符串是文本,而整型值和浮点型值都是数字。
myAge
变量包含了input()
函数返回的值。因为input()
函数总是返回一个字符串(即使用户输入的是数字),所以你可以使用int(myAge)
返回字符串的整型值。这个整型值随后在表达式int(myAge) + 1
中与1相加。
将相加的结果传递给str()
函数:str(int(myAge) + 1)
。然后,返回的字符串与字符串'You will be '
和' in a year.'
连接,求值为一个更长的字符串。这个更长的字符串最终传递给print()
函数,在屏幕上显示。
假定用户输入字符串'4'
,保存在myAge
中。字符串'4'
被转换为一个整型值,所以你可以对它加1,结果是5。str()
函数将这个结果转化为字符串,这样你就可以将它与第二个字符串'in a year.'
连接,创建最终的消息。这些求值步骤如下所示。
你可以用一个计算器来计算表达式,或在文本处理器中输入字符串连接,甚至可以通过复制粘贴文本,很容易地实现字符串复制。但是表达式以及组成它们的元素(操作符、变量和函数调用)才是构成程序的基本构建块。一旦你知道如何处理这些元素,就能够用Python操作大量的数据。
最好记住本章介绍的不同类型的操作符(+、-、*
、/、//、%和**
是数学操作符,+和*
是字符串操作符),以及3种数据类型(整型、浮点型和字符串)。
本章还介绍了几个不同的函数。print()
和input()
函数处理简单的文本输出(到屏幕)和输入(通过键盘)。len()
函数接收一个字符串,并求值为该字符串中字符的数目。str()
、int()
和float()
函数将传入它们的值求值为字符串、整数或浮点数形式。
在下一章中,你将学习如何告诉Python根据它拥有的值,明智地决定什么代码要运行、什么代码要跳过、什么代码要重复。这被称为“控制流”,它让你编写程序来做出明智的决定。
1.下面哪些是操作符,哪些是值?
*
'hello'
-88.8
-
/
+
5
2.下面哪个是变量,哪个是字符串?
spam
'spam'
3.说出3种数据类型。
4.表达式由什么构成?所有表达式都做什么事?
5.本章介绍了赋值语句,如spam = 10
。表达式和语句有什么区别?
6.下列语句运行后,变量bacon
的值是什么?
bacon = 20
bacon + 1
7.下面两个表达式求值的结果是什么?
'spam' + 'spamspam'
'spam' * 3
8.为什么eggs
是有效的变量名,而100
是无效的变量名?
9.哪3个函数能分别取得一个值的整型、浮点型和字符串形式?
10.为什么下面这个表达式会导致错误?如何修复?
'I have eaten ' + 99 + ' burritos.'
附加题:在线查找len()
函数的Python文档。查看Python的其他函数的列表,查看round()
函数的功能,并在交互式环境中使用它。