Python编程快速上手——让烦琐工作自动化(第3版)

978-7-115-68488-2
作者: 阿尔·斯维加特(Al Sweigart)
译者: 袁国忠
编辑: 胡俊英

图书目录:

详情

这是一本面向初学者的 Python 编程实用指南,用“讲故事 + 做项目”的方式带你走进Python 世界。 本书的前半部分(第 1~8 章)用浅显易懂的语言将 Python 基础知识、语法、数据结构等串起来,后半部分(第 9~24 章)则把这些概念直接投入真实场景,让 Python 程序替你批量整理文件夹、填报电子表格、抓取网页数据、生成 PDF 报告、定时发送邮件,甚至让计算机“开口说话”。本书的案例聚焦日常痛点,会先讲思路,再给代码,并在实践项目中分步骤拆解和演 示编程实践,非常有助于读者边学边上手。值得一提的是,本书还结合大语言模型(LLM)给出了一些更加巧妙的实践技巧。 无论你是想要轻松学习编程的入门级读者,还是想借助程序自动化处理事务的非专业人士,这本久经考验的 Python 教程都将是你不容错过的选择。

图书摘要

版权信息

书名:Python编程快速上手——让烦琐工作自动化(第3版)

ISBN:978-7-115-68488-2

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。


版  权

著    [美] 阿尔·斯维加特(Al Sweigart)

译    袁国忠

责任编辑 胡俊英

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315

版 权 声 明

Copyright © 2024 by Al Sweigart. Title of English-language original: Automate the Boring Stuff with Python: Practical Programming for Total Beginners, 3rd Edition, ISBN 9781718503403, published by No Starch Press Inc. The Simplified Chinese-language 3rd edition Copyright © 2026 by Posts and Telecom Press Co., Ltd under license by No Starch Press Inc. All rights reserved.

本书简体中文版由美国 No Starch 出版社授权人民邮电出版社出版。未经出版者书面许可,不得对本书任何部分以任何方式复制或抄袭。

版权所有,侵权必究。

内 容 提 要

这是一本面向初学者的Python编程实用指南,用“讲故事+做项目”的方式带你走进Python世界。

本书的第一部分(第1~8章)用浅显易懂的语言将Python基础知识、语法、数据结构等串起来,第二部分(第9~24章)则把这些概念直接投入真实场景,让Python程序替你批量整理文件夹、填报电子表格、抓取网页数据、生成PDF报告、定时发送邮件,甚至让计算机“开口说话”。本书的案例聚焦日常痛点,会先讲思路,再给代码,并在实践项目中分步骤拆解和演示编程实践,非常有助于读者边学边上手。值得一提的是,本书还结合大语言模型(LLM)给出了一些更加巧妙的实践技巧。

无论你是想要轻松学习编程的入门级读者,还是想借助程序自动化处理事务的非专业人士,这本久经考验的Python教程都将是你不容错过的选择。

对本书的赞誉

如果你是 Python新手,请先将这本书收入囊中,如果你是经验丰富的Python玩家且还没看过这本书,也请抽空读一读。

—— 摘自Medium专栏“The Startup”

把程序拆散再像拼积木一样拼回去,好玩得不得了!就像小时候搭建积木,那种快乐又回来了。

—— 威尔·惠顿(Wil Wheaton),演员、作家、极客圈大咖

想让计算机替你干苦活累活?那就读读这本书!上手快、效果立竿见影,强烈推荐!

—— 马克·吉布斯(Mark Gibbs),Network World特约专栏作家

编程最大的爽点,就是看着计算机乖乖帮你把事情办完。这本书把每一次小的成功都放大给你看,再无聊的事情也能玩出花样。

—— 希拉里·梅森(Hilary Mason),Fast Forward Labs 创始人兼Accel常驻数据科学家

每天被重复、烦琐的任务折磨?这本书就是你的救星,让你再也不用花几小时干苦力了。

—— 达克斯特·沙利文(Dakster Sullivan),GeekMom网站

无论你是喜欢看书学习,还是喜欢看视频学习,这本书都是你不容错过的!它能帮你轻松写出实用的Python程序,效率飞起!

—— 塞尔达尔·雷古拉普(Serdar Regulalp),InfoWorld网站

作 者 简 介

阿尔·斯维加特(Al Sweigart) 软件开发人员、艺术家、Python软件基金会会士(Fellow);著有多部适合初学者阅读的编程著作,其中包括Invent Your Own Computer Games with PythonThe Big Book of Small Python ProjectsBeyond the Basic Stuff with Python(均由No Starch 出版社出版);曾在多个PyCon大会上担任国际演讲嘉宾。

技术审校者简介

英文版技术审校者简介

丹尼尔·津加罗(Daniel Zingaro)博士 任教于多伦多大学计算机科学系。因以下成就蜚声海内外:开创独特的互动式教学方法、对生成式AI辅助教学的前沿研究、编写以学习者为中心的教材(被全球各地数千名学生采用)。著有Algorithmic Thinking第2版(No Starch 出版社,2024)和Learn to Code by Solving Problems(No Starch 出版社,2021),并与人合著了Learn AI-Assisted Python Programming with GitHub Copilot and ChatGPT(Manning出版社,2023)。

中文版技术审校者简介

@五里墩茶社(本名:杨威理)是一位深耕人工智能领域的技术极客与内容创作者,也是B站(即bilibili)的一名热门UP主,致力于将复杂的知识转化为通俗易懂的内容。他紧跟技术前沿,时常推出各类技术解读教程,帮助大家理解和掌握相关技术。

刘江峰,重庆大学软件工程硕士。具备技术开发背景,深耕数据分析领域,在电商、物流、旅游及制造业拥有丰富的跨界经验。目前专注于制造业数字化转型,致力于数据体系的构建与评估,为企业的数据驱动决策提供核心支撑。

我与本书作者相识已久:最初我是他的读者,后来是同事,近来成了朋友。对于编程、学习方式及人们如何和谐共处,他有着深刻的批判性思考。因此若想向人学习编程之道,再没有比他更合适的人选了。

人们想学习编程的主要原因有两个。首先,面临独特的任务或问题,需要借助代码来自动完成或解决;其次,对学习新技能有浓厚的兴趣。通常,这两个原因兼而有之。要学习编程,Python语言无疑是最佳选择,因为它拥有丰富的可下载的库,可帮你自动完成几乎任何你能想到的任务,还有大量的Python资源,可帮助你快速解决面临的问题。

本书第1版于10年前面世,展现了一种出色的著述理念,这种理念至今依然熠熠生辉。下面的事实证实了这一点:自首版付印之日起,本书就是非常好的Python学习资料,它包含大量实例,如果需要快速解决面临的问题,可以找到相应的实例并根据需要对其进行修改;如果想加深对编程的理解,实现本书中一系列真实的项目无疑是最佳途径。

当前无疑是学习Python的最佳时机。有些人对人工智能方面的炒作深信不疑,认为不用再学习编程了,因为AI(Artificial Intelligence,人工智能)工具能够替你编写所有的代码。而另外一些人则认为,AI生成的代码糟糕透顶、不堪一用。在大多数情况下,真实情况介于这两个极端看法之间。

AI工具的确能在编程工作中助你一臂之力,但如果你对编程有适当的了解,并知道如何借助编程来解决当前面临的具体问题,AI工具将能发挥更大的作用。如若不然,你很可能陷入你和AI助手都束手无策的境地。如果你结合从本书中获得的知识和理解来使用AI,就能够高效地开发出可靠且实用的工具。

这是一部出色的著作,祝你学习愉快!

《Python编程:从入门到实践》作者

埃里克·马瑟斯(Eric Matthes)

致  谢

本书封面上只有我的名字,这容易引起误解。

如果没有众多人士的鼎力相助,本书绝无可能付梓。在此衷心感谢以下人员提供的宝贵支持:出版人Bill Pollock,编辑Laurel Chun、Leslie Shen、Greg Poulos、Jennifer Griffth-Delgado、Frances Saux、Jill Franklin、Sabrina Plomitallo-González和Allison Felus,以及No Starch出版社的其他工作人员。特别感谢Ari Lacenski、Philip James和Daniel Zingaro博士提供的出色建议和支持。

万分感谢Python软件基金会每位成员的杰出贡献。感谢PyCon和DjangoCon大会组织者和志愿者的辛勤付出。感谢技术行业最杰出的Python社区。

前  言

“我们3个人原本需要两天才能完成的工作,你仅用两小时就搞定了”,这是我的大学室友于21世纪初在一家电子产品零售商店工作时的经历。这家商店时不时地需要处理电子表格,其中包含从竞争对手那里收集到的数千种商品的价格。这种电子表格由一个3人团队处理,他们将电子表格打印到厚厚的一叠纸上,再分配给不同的人进行处理。对于每件商品,都要查看本店的售价,如果高于竞争对手的售价,就将该商品标出来。这通常需要两三天才能完成。

在完成这项任务的过程中,团队成员坐在地板上,周围散落着成堆的纸张。面对此情此景,室友指出,“如果有打印件的原始电子文件,我就可以编写程序来完成这项任务”。

经过两三个小时的奋斗,室友编写出了一个简短的程序。这个程序从文件中读取竞争对手的售价,在本店数据库中查找相应的商品,再指出竞争对手的售价是否更低。他当时还是编程新手,因此大部分时间都花在阅读相关的编程书上。这个程序只用几秒就完成了任务,室友及其同事当天得以享受超长的午餐时间。

这就是计算机编程的威力所在。计算机犹如瑞士军刀,能够完成的任务数不胜数。为完成重复性任务,很多人花数小时的时间单击鼠标和敲击键盘,却没有意识到只要给出正确的指令,他们正在使用的计算机只需几秒就能完成这些任务。

为谁而写

软件是当今人们使用的众多工具的核心:几乎人人都使用社交网络进行交流,几乎所有人的包或口袋里都装着能上网的手机,大多数办公室工作都需通过与计算机交互来完成。因此,社会对编程人才的需求急剧增加。数不胜数的图书、在线教程和开发人员训练营都承诺,能够让野心勃勃的初学者脱胎换骨,成为薪资高达6位数的软件工程师。本书并非为这些人编写的,而是为除他们之外的人编写的。

就像仅靠上几节吉他课无法成为摇滚巨星一样,仅靠阅读本书也无法成为专业的软件开发人员。但如果你是办公室职员、管理人员、学术研究者或其他出于工作需要或兴趣而使用计算机的人,通过阅读本书你将学会基本的编程知识,能够自动化完成下面这样的简单任务。

重命名数以千计的文件,并将其移动到不同的文件夹中。

填写在线表单(无须手动输入)。

每当网站更新时都从网站下载文件或复制文本。

让计算机向手机发送定制的短信通知。

更新Excel电子表格的内容或格式。

查看电子邮件并发送预先编写好的回复。

创建数据库并查询其中的信息。

从图像和音频文件中提取文本。

这些任务虽然简单,但人工完成需要很长的时间;另外,它们通常琐碎而个性化,没有可用来处理它们的现成软件。然而,只要具备一些编程知识,就能够让计算机替你完成这些任务。

编码约定

本书并非参考手册,而是初学者指南。在有些情况下,本书采用的编码风格并不符合最佳实践(例如,有些程序使用了全局变量),但这样的折中让代码更易于学习。出于简化考虑,本书没有介绍复杂的编程概念,如面向对象编程、列表推导和生成器。经验丰富的程序员可能会发现,从效率的角度看,本书的代码确有优化空间,但本书的核心目标是以最轻量的方式让程序顺利运行。

版式约定

在本书中,代码行中或部分正文中都分布有形如❶❷❸等的数字,此类数字仅用于读者将相应的代码行与正文关联起来,以便更好地理解相关知识及代码的特点。

编程简介

在电视节目和电影中,我们经常看到程序员快速敲击键盘,而他前面闪闪发光的屏幕上显示的是一串串神秘的1和0,但现代编程并非如此神秘莫测。所谓编程,就是使用计算机能够理解的语言编写供计算机执行的指令。这些指令可以处理数字、修改文本、在文件中查找信息或通过互联网与其他计算机通信。

所有程序都由基本指令组成,下面是几个使用自然语言描述的常见指令。

先做这个,再做那个。

如果满足这个条件,就执行这个操作;否则就执行那个操作。

执行这个操作27次。

不断做这个操作,直到满足那个条件为止。

还可以结合使用这些基本指令做出更复杂的决策。例如,下面是使用编程语言Python编写的一个简单程序的编程指令(源代码),这个程序按顺序执行代码行(有些代码行仅在条件满足或不满足时才执行),直到到达程序末尾:

❶ password_file = open('SecretPasswordFile.txt')
❷ secret_password = password_file.read()
❸ print('Enter your password.') 
  typed_password = input()
❹ if typed_password == secret_password: 
    ❺ print('Access granted')
    ❻ if typed_password == '12345':
        ❼ print('That password is one that an idiot puts on their luggage.')
  else:
    ❽ print('Access denied')

即便没有任何编程知识,你也能够通过阅读上述代码并猜到这段代码是做什么的。首先,打开文件SecretPasswordFile.txt ❶,并读取其中的密码❷。然后,提示用户通过键盘输入密码❸,并对这两个密码进行比较❹。如果它们相同,就在屏幕上显示Access granted ❺,并检查密码是否为12345 ❻;如果是,就提示选择使用这样的密码不明智(即显示That password is one that an idiot puts on their luggage.)❼。如果这两个密码不同,就在屏幕上显示Access denied ❽。

就像绘画、写作、编织和搭积木一样,编程也是一种创造性活动。就像在空画布上画画一样,软件开发也受制于众多约束条件,但又有无限的可能性。相比于其他创造性活动,编程的独特之处在于,计算机自带了编程所需的各种原材料,因此无须额外购买画布、颜料、胶片、毛线、积木和电子元件。程序编写好之后,就可以复制无数次。一件针织毛衣每次只能供一人穿,但程序可以轻松地以在线方式与整个世界分享。

Python简介

Python可以指编程语言(包含编写合法Python代码必须遵守的规则),也可以指读取使用Python编写的源代码并执行其中指令的解释器软件。你可以前往Python官网免费下载用于Windows、macOS和Linux系统的Python解释器。

编程语言有很多,它们各有优缺点,争论哪种语言最出色常常会引出对证明观点没有意义的论据。在我看来,对编程新手来说,先学习Python是最佳选择。Python易于学习,其语法也容易理解;无须学习大量概念就可以使用它来完成简单的任务;另外,如果要深入研究编程,先学会Python再学习其他语言将更容易。

Python语言的名字来自英国超现实主义喜剧团Monty Python,而不是蟒蛇。Python 程序员被亲切地称作Pythonistas;在Python教程和文档中,经常会提及喜剧团Monty Python和蟒蛇。

拋弃谬误,重新看待编程

编程常被认为高深莫测,软件巨头企业更是家喻户晓,甚至在英语中,单词code本身也暗含机密与晦涩之意。这导致很多人都以为只有少数人能够胜任编程工作,实际上,编程是任何人都能学会的技能。下面带你真正认识编程。

程序员无须具备很多数学知识

对于学习编程,最常见的担心是需要掌握大量数学知识。实际上,大多数编程工作并不要求掌握基本算术运算外的其他数学知识。对编程而言,推理能力和对细节的关注比数学知识更重要。实际上,编程与解决数独问题没有什么不同。

解决数独问题时,需要在9×9棋盘的每行和每列都填入数字1~9,同时确保每个内部3×3网格都包含数字1~9。在数独问题开始时,9×9棋盘中已经填入了一些数字,你需要根据这些数字做出推理,进而找到答案。在图1所示的数独问题中,数字5已经出现在第1行和第2行,因此它不能再次出现在这些行中。据此可知,在右上角的3×3网格中,数字5必然出现在第3行中。因为数字5已经出现在最后一列中,所以它不能出现在数字6的右边,那么它必然出现在数字6的左边。每确定一个单元格中的数字,都为解决问题提供了更多线索。随着你在各行、各列或各个3×3网格中填入数字1~9,整个数独问题很快就能得到解决。

图1  一个数独问题(左)及其答案(右)。数独问题虽然使用数字,但并不涉及太多的数学知识

数独问题涉及数字,但这并不意味着必须精通数学才能找到答案。编程亦如此。与解决数独问题一样,编程也需关注细节,并将问题分解为一系列小步骤。同理,调试程序(即找到并修复错误)时,需要耐心观察程序在做什么,进而找出导致问题的原因。与学习其他技能一样,编写的程序越多,编程水平就越高。

什么时候学习编程都不晚

对于学习编程,第二个常见的顾虑是担心过了最佳学习年龄。网上有很多评论说,自己都23岁了,学习编程太晚了。这个年龄学习编程显然并不晚,因为很多人开始学习编程时年龄比23岁要大得多。

即便没有从小学习编程,也能成为出色的程序员,但“程序员都很神通”的印象的确深入人心。遗憾的是,当我跟人说我从小学就开始学习编程时,也为这种谬误的传播贡献了一份力量。

然而,相比于20世纪90年代,如今学习编程要容易得多,因为可供参考的书籍更多、搜索引擎更出色、在线的问答网站更多、编程语言本身对用户也更友好。鉴于此,以前我从小学到高中毕业期间学到的所有编程知识,现在可能只需十多个周末就能学会;换言之,我虽然赢在了起跑线上,但并没有领先多少。

对编程秉持成长思维很重要,换言之,必须明白编程技能是通过实践得以提高的。谁也不是天生就是程序员,现在不熟悉编程并不意味着永远成不了专家。

AI不会取代程序员

20世纪90年代,纳米技术被认为有望改变一切。大家普遍认为,新的制造工艺和科学发明将彻底改变社会。借助大小与细菌相当的纳米机器人,可以通过每次添加一个碳原子的方式组装出碳纳米管、巴基球和钻石(其造价像铅笔芯一样低廉)。这样一来,我们就能制造出强度为钢铁的10倍,而重量和造价却低得多的材料。借助这些技术,有望铺设太空电梯、创造医学奇迹、制造出能够创造一切的家用电器(犹如《星际迷航》中的复制机)。这意味着资源稀缺、全球性饥饿和战争的终结,世界将进入一个智慧的新时代,但前提条件是纳米机器人不会奋起反抗,将创造它们的人类推翻。那时有人认为,这样的技术有望在10年内面世。

当然,这种被大肆宣传的前景并未成为现实。在纳米技术领域,确实有真正意义的创新,智能手机就使用了众多这样的技术,但《星际迷航》中的复制机和其他宏大的愿景并未实现,人们对纳米技术的看法也变得现实了很多。

下面来说说AI。

个人计算机改变了一切,互联网改变了一切,社交媒体改变了一切,智能手机改变了一切,加密货币并未改变一切,但确实揭示出了你的哪些远亲和同事容易陷入一夜暴富的骗局。当前,技术行业出现的最新奇迹无疑是AI,人们用它来指代从下棋的计算机到聊天机器人,以及所谓的专家系统和机器学习等。本书使用AI来指代大语言模型(Large Language Model,LLM),这是一个概念范畴,涵盖OpenAI的ChatGPT、Google的Gemini、Meta的Llama和其他生成式文本系统。

LLM引发了众多令人目瞪口呆的断言和问题。AI会让所有人失业吗?现在还值得去学习编程吗?AI有生命吗?在这场AI机器人革命中,我能全身而退吗?

LLM技术激动人心,但要让它发挥作用,我们不能有不切实际的期望,以免因相信哗众取宠的新闻和可疑的投资机会而成为受害者。但愿我能帮你戳破泡沫,真正看清LLM能够在学编程这件事情上给你提供什么帮助。我们现在就来重申一些正确的观念。

LLM没有意识和知觉。

LLM不会取代人类软件工程师。

LLM并不能让你绕过学编程这一步,该学的还是得学。

LLM不能取代大多数人的工作(但并不排除管理层可能会那样想,进而将你辞退)。

LLM远远谈不上完美,甚至会经常犯错。

那些抱有错误执念的人,他们的信息来源多半是科幻电影和网络短视频,而非实际的LLM使用经验。Simon Willison是Python软件基金董事会成员和Web框架Django的联合创始人,我强烈建议你阅读他就AI相关话题撰写的文章,并观看他在PyCon 2024大会上就LLM发表的充满智慧和启迪的主旨演讲。

LLM可以为程序员提供什么样的帮助呢?在当前LLM发展的早期阶段,显然学习如何与LLM沟通(所谓的“提示词工程”)是一项重要技能,就像学会有效地使用搜索引擎是一项重要技能一样。LLM不是人,因此你需要学习如何正确地提问才能得到中肯而可靠的答案。当LLM信心满满地编造错误的答案时,我们说它出现了“幻觉”,但这将算法拟人化了。LLM不思考,只是生成文本,也就是说,LLM总是会出现幻觉,即便答对了,也只是巧合。

LLM既会犯严重且显而易见的错误,也会犯小而微妙的错误。如果要将其用作学习助手,请务必保持警惕,对它告诉你的一切都进行核实——无论是重点还是细节。完全不借助LLM学习仍然是合理的选择。到目前为止,LLM在教育领域的有效性还未得到证明,我们并不确定LLM在什么情况下是有效的学习工具,甚至都不确定它带来的好处是否超过了为此付出的代价。

如此多的人相信有关LLM的大肆宣传并没有什么奇怪的。我们装在口袋里的设备(智能手机)在20世纪的科学家看来就是超级计算机。它们让全球信息(包括错误信息)变得触手可及,不管身处地球的什么地方,通过卫星通信,它们都能够快速实现定位。软件确实能够做些神奇的事情,但软件并非万能。通过学习编程,你会对哪些确实在计算机的能力范围内、哪些不过是炒作,拥有更准确的认识。

涵盖的内容

本书分两部分,其中第一部分介绍如何使用Python编程,第二部分介绍可以用来自动完成各种任务的Python库。建议先按顺序阅读第一部分的全部内容,再根据自己的兴趣有选择地阅读第二部分的内容。下面简要地说明一下各章涵盖的内容。

第一部分:编程基础

第1章介绍表达式和最基本的Python指令,以及如何使用Python交互式环境来尝试执行代码。

第2章介绍如何让程序决定执行哪些指令,让代码能够根据条件做出明智的响应。

第3章介绍如何让程序重复执行指令,直到执行了指定次数或不满足指定的条件。

第4章介绍如何定义函数,以便将代码组织成易于管理的模块。

第5章介绍如何使用Python提供的各种工具查找和修复bug。

第6章介绍列表和数据组织技巧。

第7章介绍字典和更强大的数据组织技巧。

第8章介绍如何处理文本数据(Python称之为字符串)。

第二部分:任务自动化

第9章介绍在Python中如何使用正则表达式来操作字符串和查找文本模式。

第10章介绍如何读取文本文件的内容,以及如何将数据保存到硬盘文件中。

第11章介绍如何借助Python以比人类用户快得多的速度复制、移动、重命名和删除大量文件,还将介绍如何压缩和解压缩文件。

第12章介绍如何将Python程序打包,以便能够在本地计算机或协作的计算机上轻松地运行它们。

第13章介绍如何编写自动下载网页并对其中的信息进行解析的程序(又称“爬虫”程序)。

第14章介绍如何通过编程操作Excel电子表格,当你需要分析数百乃至数千个表格时,这可以提供极大的帮助。

第15章介绍如何使用Python读取和更新由Google Sheets创建的电子表格。

第16章介绍如何使用Python自带的强大开源数据库软件SQLite处理关系数据库。

第17章介绍如何通过编程读取PDF和Word文档。

第18章介绍如何通过编程操作数据序列化格式(CSV、JSON和XML)的文档。

第19章介绍如何在Python程序中处理时间和日期,如何调度计算机使其在特定时间执行任务,以及如何在Python程序中启动其他程序。

第20章介绍如何编写程序,使其能够通过电子邮件、手机短信、推送消息等方式向自己或他人发送自动化提醒。

第21章介绍如何通过编程操作图像(如JPEG或PNG文件),以及如何使用Matplotlib库绘制图表。

第22章介绍如何使用PyTesseract包提取图像和扫描文档中的文本,以便做进一步的处理。

第23章介绍如何通过编程来控制鼠标和键盘,以自动化鼠标单击和键盘按键操作。

第24章介绍如何使用高级计算机科学包在文本和语音之间进行转换。

要下载本书示例的源代码及其用到的其他资源,可前往异步社区网站。

下载并安装Python

请前往Python官网,免费下载用于Windows、macOS和Ubuntu Linux的Python解释器。

下载网页会检测你的计算机所使用的操作系统,并推荐应下载的包。对于移动操作系统Android和iOS,有非官方的Python安装程序,但这些不在本书的讨论范围内。Windows、macOS和Linux都有其独特的安装选项,请根据你使用的操作系统下载相应的安装程序,再运行这个程序以安装Python解释器。

下载并安装Mu

Python解释器用于运行你编写的程序,而Mu编辑器用于输入程序,输入方式类似于在文字处理软件中输入文字。要下载Mu,可前往Mu编辑器的官网。

如果你使用的是Windows或macOS操作系统,请下载相应的安装程序,再双击运行它。在macOS系统中运行这个安装程序时,会打开一个窗口,你必须将其中的Mu图标拖曳到文件夹Applications中才能继续安装。如果你使用的是Ubuntu Linux系统,需要像安装包那样安装Mu。要查看有关如何安装的详细说明,请单击相应的Instructions按钮。

启动Mu

安装好Mu后,可以像下面这样启动它。

在Windows系统中,单击屏幕左下角的“开始”图标,在搜索框中输入Mu,再选择“Mu”。

在macOS系统中,打开Finder窗口,再依次单击Applications和mu-editor。也可以在Spotlight中打开Mu。

在Ubuntu Linux系统中,依次选择Applications > Accessories > Terminal,再输入python3-m mu并按Enter键。

首次运行Mu时,会出现Select Mode窗口,其中包含Adafruit CircuitPython、BBC micro:bit、Pygame Zero、Python 3等选项,请选择Python 3。如果后续想修改模式,可单击编辑器窗口顶部的Mode按钮。

启动IDLE

本书将Mu作为编辑器,还将使用它提供的交互式环境。当然,你也可以使用任何编辑器来编写Python代码。安装Python时,会同时安装集成开发和学习环境(Integrated Development and Learning Environment,IDLE)。如果由于某种原因无法安装或运行Mu,可以将IDLE作为Python代码编辑器。启动IDLE的方法如下(假设你安装的是Python 3.13)。

在Windows系统中,单击屏幕左下角的“开始”图标,在搜索框中输入IDLE并按Enter键,再选择IDLE (Python 3.13 64-bit)。

在macOS系统中,打开Finder窗口,再依次单击Applications、Python 3.13和IDLE图标。也可以在Spotlight中运行IDLE。

在Ubuntu Linux系统中,选择Applications > Accessories > Terminal,再输入idle并按Enter键。也可以单击Ubuntu Linux系统边栏末尾的Show Apps,再单击IDLE。

交互式环境

运行Mu时,出现的窗口称为文件编辑器窗口。在这个窗口中,单击REPL按钮可以打开交互式环境,让你能够向计算机发出指令,就像在终端窗口(macOS)或命令提示窗口(Windows)中向计算机发出指令一样。Python解释器会立即运行任何在Python交互式环境中输入的指令。

在Mu中,交互式环境是一个位于窗口下半部分的窗格,其中包含类似于下面的内容:

Jupyter QtConsole
Python 3
Type 'copyright', 'credits' or 'license' for more information
IPython -- An enhanced Interactive Python. Type '?' for help.
 
In [1]:

运行IDLE时,首先出现的是交互式环境窗口,其中只包含类似于下面的内容:

>>>

In [1]:和>>>都被称为提示符。在本书的示例中,将使用提示符>>>来表示交互式环境,因为它更常见。从终端窗口或命令提示窗口运行Python时,也将使用提示符>>>。提示符In [1]:来自另一款流行的Python编辑器——Jupyter Notebook。

例如,在交互式环境中,如果在提示符右边输入下面的代码并按Enter键:

>>> print('Hello, world!')

作为回应,交互式环境将显示如下内容:

>>> print('Hello, world!')
Hello, world!

这里你向计算机发出了一条指令,而计算机按你的命令执行了操作。

寻求帮助

程序员喜欢通过在网上查找问题的答案来学习,这不同于传统的学习方式——向现场授课的老师学习并请教问题。以网络为学习平台的优点是,整个社区的人都可以帮助你解决问题。实际上,你面临的问题可能有人解答过,因此答案就在网上等着你去寻找。如果运行代码时出现错误消息或者代码无法正确运行,你可能不是遇到这种问题的第一人,因此可能更容易找到解决方案。

例如,我们来有意地引发一个错误:在交互式环境中输入'42' + 3。结果将类似于下面这样(你现在无须知道这条指令的含义):

  >>> '42' + 3
❶ Traceback (most recent call last):
    File "<pyshell#0>", line 1, in <module>
        '42' + 3
❷ TypeError: can only concatenate str (not "int") to str
  >>>

出现了一条错误消息❷,因为Python无法理解你发出的指令。在这条错误消息中,Traceback部分❶指出了给Python带来麻烦的指令及其所在行的行号。当出现错误消息时,如果不知道该怎么办,你可以在网上搜索相应的错误消息。

为此,你可以在搜索引擎中输入“TypeError: can only concatenate str (not "int") to str”(包括标点符号),这时将出现大量说明错误消息的含义和原因的链接,如图2所示。

图2 搜索错误消息得到的结果可能提供极大的帮助

你常常会发现,已经有人遇到过同样的问题,而且有乐于助人的人做出了解答。没有人能掌握所有的编程知识,因此对任何软件开发人员来说,查找技术问题的答案都是其日常工作的一部分。

正确地提出编程问题

如果在网上找不到答案,可尝试前往Stack Overflow或Reddit网站“learn programming”板块这样的网络论坛提问。但别忘了,要让人乐意帮忙解答,必须以正确的方式提出问题。首先,务必阅读这些网站的常见问题(Frequently Asked Questions)部分,了解正确的提问方式。

在提出编程相关的问题时,请牢记如下几点。

指出你想要做什么,而不仅仅是你做了什么,让帮助者知道你的方向是否正确。

指出错误是在什么时候发生的:发生在程序刚开始运行时,还是你执行了某种操作后。

将完整的错误消息和代码复制并粘贴到pastebin网站或GitHub网站(这些网站让你能够轻松地与人分享大量代码,且不会丢失文本格式设置),这样就可以将代码的URL加入电子邮件或论坛帖子中。

指出你为解决问题做了哪些尝试,让其他人知道你为解决问题做出了努力。

指出所使用的Python版本,并指出所使用的操作系统及其版本。

如果错误是在修改代码后出现的,请准确地说明做了哪些修改。

指出错误在你每次运行程序时都会出现,还是只在你执行了特定操作时才出现。如果是后一种情况,还需说明你执行了什么操作。

另外,务必遵守良好的网络社交礼仪。例如,提问时不要使用全大写,不向帮助者提出无理要求。

关于第3版的说明

第3版做了全面修订,精心设计了16个编程项目,让读者能够将学到的技能付诸实践。书中全面介绍了SQLite及如何使用Python的sqlite3模块操作关系数据库,如何在Windows、macOS和Linux系统中将Python程序编译为可执行程序,以及如何创建和运行命令行程序。书中还介绍了如何使用PyPDF和PdfMiner执行PDF操作,如何使用Playwright和Selenium 控制Web浏览器,如何使用文本转语音库,以及如何使用OpenAI Whisper库将音频和视频文件转为文本,如何使用PyTesseract提取图像中的文本,如何使用Matplotlib创建图表。

小结

对大多数人来说,计算机只是设备,而非工具。但通过学习编程,你可以将它变成现代社会最强大的工具之一。编程不是脑外科手术,业余爱好者也可以尝试,即便犯错也没多大关系,越折腾越有趣。

本书假定读者不具备任何编程知识,但学海无涯,在编程之旅上,知道如何有效地提问和寻找答案才是最宝贵的技能。

让我们开始吧!

资源与支持

资源获取

本书提供如下资源:

案例素材;

配套源代码;

本书习题及参考答案;

本书实践项目;

Python排障手册;

Python学习效率手册;

本书思维导图;

异步社区30天VIP会员。

要获得以上资源,您可以扫描下方二维码,根据指引领取。

提交错误信息

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区(https://www.epubit.com),按书名搜索,进入本书页面,单击“发表勘误”,输入相关错误信息,单击“提交勘误”按钮即可(见下图)。本书的作者和编辑会对您提交的错误信息进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。

与我们联系

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们。

如果您所在的学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。

关于异步社区和异步图书

“异步社区”是由人民邮电出版社创办的IT专业图书社区,于2015年8月上线运营,致力于优质内容的出版和分享,为读者提供高品质的学习内容,为作译者提供专业的出版服务,实现作者与读者在线交流互动,以及传统出版与数字出版的融合发展。

“异步图书”是异步社区策划出版的精品IT图书的品牌,依托于人民邮电出版社在计算机图书领域的发展与积淀。异步图书面向IT行业以及各行业使用IT的用户。

第一部分 编程基础

第1章 Python基础

Python语言涵盖大量语法结构、标准库函数和交互式开发环境功能,好在对于其中的很大一部分,你都可以不予理会,只需学习很少一部分,就能编写出一些称手的小程序。

为此,你必须掌握一些编程概念。你可能认为,这些概念就像魔法中的咒语一样单调乏味,但经过一段时间的练习后,就能借助它们让计算机完成不可思议的壮举,就像魔法师借助咒语来实施魔法。

下面首先介绍Python交互式环境,强烈建议在阅读过程中输入本章的示例代码。Python交互式环境也被称为REPL(read-evaluate-print-loop,读取-评估-输出-循环),用于以每次一条的方式运行(执行)Python指令,并立即查看执行结果。交互式环境对了解基础Python指令的作用非常有帮助,务必在阅读本书的过程中尝试使用它:相比于仅仅阅读,辅以实践有助于更牢靠地掌握相关知识。

1.1 在交互式环境中输入表达式

要运行Python交互式环境,可在Mu编辑器中进行;有关如何下载并安装Mu,请参阅本书前言。在Windows系统中,打开“开始”菜单,输入Mu,即可打开Mu编辑器;在macOS系统中,打开Applications文件夹,再双击其中的Mu,即可打开Mu编辑器。在Mu编辑器中,单击New按钮,并将新建的空文件保存为blank.py。单击Run按钮或按F5运行这个空文件,这将打开Python交互式环境——一个位于Mu编辑器窗口底部的新窗格。在这个交互式环境中,显示了提示符>>>。

你也可以在命令行终端启动Python交互环境。在macOS和Linux系统中,请打开系统自带的终端后,直接输入python3即可。在Windows系统中,请打开Windows 终端或使用传统的命令提示符,并在其中输入python即可。

当你看到提示符>>>,说明已顺利进入交互式解释器。此时,若想运行脚本,只需在具体命令后加上.py文件路径,例如:

针对macOS和Linux系统,请使用python3 blank.py ;

针对Windows系统,请使用python blank.py 。

特别提醒

在macOS中,如果单独输入python,有时会唤起系统自带的 Python 2.7(该版本已停止维护,与新版Python语法不兼容)。

若出现警告消息“WARNING: Python 2.7 is not recommended.”,请先退出Python 2.7交互式环境,再改用python3。

在提示符下输入2 + 2并按Enter键,让Python做些简单的数学运算。此时,Mu编辑器将包含类似下面的内容:

>>> 2 + 2
4
>>>

在Python中,2 + 2被称为表达式——Python语言中最基本的编程指令。表达式由值(如2)和运算符(如+)组成,可进一步计算(即化简)为单个值。这意味着在Python代码中,可在任何可使用值的地方使用表达式。

在前面的示例中,表达式2 + 2的计算结果为单个值4。单个值(没有运算符)也被视为表达式,只是这种表达式的计算结果为其自身,如下所示:

>>> 2
2

Mu编辑器中有一个REPL按钮,单击它将显示提示符类似于In [1]:的交互式环境,流行的Jupyter Notebook编辑器使用的就是这种交互式环境,其用法与提示符为>>>的常规Python交互式环境类似。REPL并非Python所特有,很多编程语言都提供了REPL,以方便你尝试执行它们的代码。

出错很正常

一步一步地执行指令是计算机最大的优点,也是其最大的缺点。计算机不能基于常识确定你的真实意图,因此当程序包含计算机无法理解的代码时,程序将崩溃,Python随即拋出错误消息。错误消息并不会损坏计算机,因此不要害怕犯错。崩溃仅仅意味着程序意外地停止执行。

要对程序报错习以为常,因为即便有几十年的编程经验,也会经常遇到错误消息。错误消息的含义常常含混不清,对于初学者来说,并不容易立即理解。当程序出现错误时,要对其有更深入的认识,可在网上使用错误消息进行搜索,以获取有关错误的更多信息。在Mu编辑器中,可使用键盘快捷键Ctrl+Shift+C将交互式环境窗格中选定的文本复制到剪贴板,要将主文件编辑器窗格中选定的文本复制到剪贴板,可使用键盘快捷键Ctrl+C。

编程中会涉及一些你可能不太熟悉的数学运算。

乘方(幂)运算:类似于乘法运算,只是乘法运算将自身相加n次,而乘方运算将自身相乘n次。例如,2的4次方(2的4次幂)可表示为24或2**4,意思是将2自身相乘4次,即24 = 2 × 2 × 2 × 2 = 16。

求模运算:计算除法运算的余数,例如,14 % 4的结果为2,因为14除以4的商为3,余数为2。在Python中,求模运算符为% ,与百分比毫无关系。

整数除法:类似于普通除法,但将结果向下取整。例如,25 / 8的结果为3.125,但25 // 8的结果为3;29 / 10的结果为2.9,但29 // 10的结果为2。

在Python表达式中,还可使用许多其他运算符。表1-1列出了Python支持的所有数学运算符。

表1-1 数学运算符

运算符

运算

示例

结果

**

乘方

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语法,Python将无法理解,进而显示SyntaxError错误消息,如下所示:

>>> 5 +
  File "< python-input-0>", line 1
    5 +
      ^
SyntaxError: invalid syntax
>>> 42 + 5 + * 2
  File "<python-input-0>", line 1
    42 + 5 + * 2
             ^
SyntaxError: invalid syntax

要检查指令是否有效,可在交互式环境中输入并执行它。不用担心这样做会损坏计算机,最糟的结果不过是出现一条错误消息。专业软件开发人员在编写代码时也经常会遇到错误消息。

1.2 整型、浮点型和字符串数据类型

前面说过,表达式由值和运算符组合而成,其结果为单个值。数据类型是特定类型的值,而每个值都只属于一种数据类型。表1-2列出了Python中常见的数据类型。例如,值-2和30被归入整数值。整数数据类型表明值为整数;带小数点的数字(如3.14)被称为浮点数。请注意,值42为整数,但值42.0为浮点数。程序员通常将整数和浮点数统称为数字,但在Python中,并没有“数字”这种数据类型。

对于Python,一个需要注意的细微之处是,同时涉及整数和浮点数的数学运算的结果为浮点数,而不是整数。例如,虽然表达式3 + 4的结果为整数7,但表达式3 + 4.0的结果为浮点数7.0。使用运算符/对两个整数执行除法运算时,结果也是浮点数。例如,16 / 4的结果为4.0,而不是4。在大多数情况下,这一点对程序来说都无关紧要,但知道这一点后,在数字中突然出现小数点时,你将明白其中的原因所在。

表1-2 常见的数据类型

数据类型

示例

整数(int)

-2、1、0、1、2、3、4、5

浮点数(float)

-1.25、-1.0、-0.5、0.0、0.5、1.0、1.25

字符串(str)

'a'、'aa'、'aaa'、'Hello!'、'11 cats'、'5'

在Python程序中,还可使用文本值,这种文本值被称为字符串。对于文本值,总是用单引号字符(')将其括起,如'Hello'或'Goodbye cruel world!',这旨在让Python知道字符串的起始位置和结束位置。甚至有不包含任何字符的字符串(''),这被称为空字符串。字符串将在第8章做更详细的介绍。

你可能遇到类似于下面这样的错误消息:

>>> 'Hello, world!
SyntaxError: unterminated string literal (detected at line 1)

这种错误消息可能表明你遗漏了字符串末尾的单引号。

1.3 字符串的拼接和复制

当运算符两边的值的数据类型发生变化时,运算符的含义可能随之变化。例如,用于对两个整数或浮点数执行运算时,+为加法运算符,但作用于两个字符串值时,+为字符串拼接运算符,将两个字符串拼接为一个。请在交互式环境中输入下面的代码:

>>> 'Alice' + 'Bob'
'AliceBob'

这个表达式的结果为单个字符串值,由表达式中两个字符串的文本合并而成。然而,如果将运算符+用于一个字符串值和一个整数值,Python将不知道该如何做,进而显示一条错误消息:

>>> 'Alice' + 42
Traceback (most recent call last):    
    File "<python-input-0>", 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'

这个表达式的结果为单个字符串值,它重复了原始字符串n次,其中n由*后面的整数值指定。字符串复制是一个很有用的技巧,但不如字符串拼接那样常用。

运算符*用于两个数值(表示乘法运算)之间,或一个字符串值和一个整数值(表示字符串复制)之间,否则Python将显示一条错误消息,如下所示:

>>> 'Alice' * 'Bob'
Traceback (most recent call last):
    File "<python-input-0>", 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 "<python-input-0>", line 1, in <module>
    'Alice' * 5.0
TypeError: can't multiply sequence by non-int of type 'float'

Python无法理解这些表达式,这合乎情理,因为无法将两个单词相乘,而复制字符串时,复制次数不能是小数。

就目前而言,表达式、数据类型和运算符可能对你来说显得很抽象,但对这些概念有更深入的认识后,你将能够创建更复杂的程序,并在其中对来自电子表格、网站、其他程序和地方的数据执行数学运算。

1.4 在变量中存储值

变量类似于计算机内存中的一个盒子,可在其中存放单个值。在程序中,如果要在后面使用计算得到的表达式结果,可将其存储到变量中。

1.4.1 赋值语句

要将值存储到变量中,可使用赋值语句。赋值语句由变量名、等号(被称为赋值运算符)和要存储的值组成。如果你输入赋值语句spam = 42,变量spam中将保存整数值42。

可将变量视为带标签的盒子,其中存储了值,但更好的比喻可能如下:变量是与值相关联的标签,个中原因将在第6章阐述。图1-1说明了这两种比喻。

图1-1 代码spam = 42告诉程序,变量spam当前存储的是整数值42

请在交互式环境中输入如下代码:

❶ >>> 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'

在这个示例中,变量spam中存储的是'Hello',直到你将这个字符串替换为'Goodbye',旧值将被覆盖,如图1-2所示。

图1-2  给变量赋新值时,旧值被覆盖

你也可以把“覆盖变量”理解为将原本贴在某个值上的名字标签撕下来,再贴到新的值上。

1.4.2 变量名

好的变量名描绘了变量包含的数据。设想一下,如果搬家时将所有箱子的标签都标为“物品”,搬家后就无法快速找到所需的东西。在本书的大部分示例(以及Python文档)中,使用的都是不那么具体的变量名,如spam、eggs和bacon[这些名称源自英国六人喜剧团“巨蟒组”(Monty Python)表演的滑稽小品Spam]。在你自己编写的程序中,务必使用描述性变量名,因为这有助于提高代码的可读性。

在命名方面,Python做了一些限制,具体地说,变量名必须遵循如下4条规则。

不能包含空格。

只能包含字母、数字和下划线(_)。

不能以数字开头。

不能是Python关键字,如if、for、return(以及本书将介绍的其他关键字)。

表1-3列出了一些有效和无效的变量名。

表1-3 有效和无效的变量名

有效变量名

无效变量名

current_balance

current-balance(不能包含连字符)

currentBalance

current balance(不能包含空格)

account4

4account(不能以数字开头)

_42

42(可以以下划线开头,但不能以数字开头)

TOTAL_SUM

TOTAL_$UM(不能包含诸如$等特殊字符)

hello

'hello'(不能包含诸如'等特殊字符)

变量名是区分大小写的,这意味着spam、SPAM、Spam和sPaM是4个不同的变量。在Python中,约定俗成的做法是,变量名以小写字母开头(变量名spam符合这种约定,而Spam不符合)。

编码风格和PEP 8

在本书的前两版中,变量名使用的是驼峰命名法(即变量名类似于lookedLikeThis),而不是用下划线分隔不同的单词(即looking_like_this)。后面这种形式被称为蛇形命名法,因为不同单词之间的下划线看起来像小蛇(而驼峰命名法中的大写字母看起来像驼峰)。有些经验丰富的程序员指出,Python官方编码风格文档(PEP 8)规定应使用下划线。然而,作者喜欢使用驼峰命名法也没有错,毕竟PEP 8也提到“不加思考地遵循实属愚不可及”(A Foolish Consistency Is the Hobgoblin of Little Minds)。

PEP 8还强调,“与PEP 8保持一致很重要,但更重要的是知道在什么情况下不遵循PEP 8,因为在有些情况下,PEP 8根本就不适用。在心存疑惑的情况下,请根据自己的判断做出选择”。

计算机并不在乎你使用的是哪种编码风格,且PEP 8并非铁律,神圣不可侵犯。具体使用哪种编码风格无关紧要,只要始终采用相同的编码风格即可。为证明这一点,作者采用蛇形命名法重写了第3版的配套代码(实际上,无论采用哪种命名法都无关紧要)。

1.5 编写第一个程序

交互式环境很适合用来以每次一条的方式运行Python指令,但要编写完整的Python程序,必须在文件编辑器中输入指令。文件编辑器类似于记事本和TextMate等文本编辑器,但提供了一些专为方便输入源代码的功能。在Mu编辑器中,要新建文件,可单击顶端的New按钮。

这将新建一个选项卡,其中的光标表明正等待你输入代码。在交互式环境中,Python在你按Enter键后立即运行输入的指令,而Mu编辑器让你能够输入大量的指令,将这些指令保存到文件中,再运行整个程序。如何区分交互式环境和Mu编辑器呢?方法如下。

交互式环境始终包含提示符>>>或In [1]:。

Mu编辑器没有提示符>>>或In [1]:。

下面来创建你的第一个程序。在Mu编辑器中新建一个选项卡后,在其中输入如下代码:

# 这个程序会跟用户打招呼并要求用户提供其姓名。
 
print('Hello, world!')
print('What is your name?') # 要求用户提供其姓名
my_name = input('>')
print('It is good to meet you, ' + my_name)
print('The length of your name is:')
print(len(my_name))
print('What is your age?') #要求用户提供其年龄
my_age = input('>')
print('You will be ' + str(int(my_age) + 1) + ' in a year.')

输入这些源代码后,将其保存到文件中,以免重启Mu后需要重新输入它们。为此,单击Save按钮,在File Name文本框中输入hello.py,再单击Save按钮。

输入程序代码时,应每隔一段时间存盘一次,这样即便计算机崩溃或不小心关闭了Mu,也不会丢失代码。要保存文件,可使用快捷键:在Windows和Linux系统中,快捷键为Ctrl+S;在macOS系统中,快捷键为+S。

将这个程序保存到文件后,咱们来运行它。为此,按F5键或单击Run按钮。在程序询问时,输入你的姓名。程序的输出将出现在交互式环境中,它们类似于下面这样:

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程序已退出)。程序终止后,Mu编辑器将显示交互式环境提示符>>>,以方便你输入并执行其他的Python代码。

要关闭文件,可单击相应选项卡标签右端的×,这类似于关闭浏览器选项卡。要重新加载已保存的程序,请在菜单中单击Load。现在就请这样做,并在出现的对话框中选择hello.py,再单击Open按钮。这将在一个新的文件编辑器窗口中打开前面保存的程序hello.py。

要查看程序的分步执行过程,可使用可视化工具Python Tutor。在这个工具中,单击前进按钮可让程序往下执行一步,这让你能够看到变量值和输出是如何变化的。

1.6 程序详解

在Mu编辑器中重新打开你的第一个程序后,下面来看看每行代码的作用,并简单地说说该程序使用的Python指令。

1.6.1 注释

下面这行代码为注释:

# 这个程序会跟用户打招呼并要求用户提供其姓名

Python会自动忽略注释,但你可以使用它们来提供说明或指出代码想要做什么。从井字符(#)到行尾的所有内容都是注释。

测试程序时,程序员有时会在代码行开头添加#,以便暂时将相应的代码行从程序中删除,这种做法被称为“将代码注释掉”。在想要搞清楚程序为何不能正确运行时,这种方法可能很有用。后续要恢复被注释掉的代码行时,只需将相应的#删除。

Python还会忽略位于前述注释后面的空行。在程序中,可以根据需要添加任意数量的空行;就像书籍中的分段一样,这种分隔方式使代码阅读起来更轻松。

1.6.2 函数print()

函数print()会将括号内的字符串值显示在屏幕上:

print('Hello, world!')
print('What is your name?') #要求用户提供其姓名

代码行print('Hello, world!')的意思是,输出字符串'Hello, world!'中的文本。Python执行这行代码时,意味着Python正在调用函数print(),同时将前述字符串值传递给了这个函数。向函数传递的值被称为实参。注意到,单引号并未显示到屏幕上,因为它们是字符串起始和结束位置的标识,而非字符串本身的一部分。

注意 函数print()还可用来在屏幕上显示一个空行,只需在调用它时不在括号内指定任何内容即可。

调用函数时,需要在它后面添加左括号和右括号,这表明它是函数名,这就是为什么在本书中你会看到print()(而非print)。标准做法是在函数名和左括号之间不添加空格,但Python并未要求必须这样做。第3章会更详细地介绍函数。

1.6.3 函数input()

函数input()等待用户通过键盘输入一些文本并按下Enter键:

my_name = input('>')

在这行代码中,函数调用返回由用户输入的文本组成的字符串,而其他的代码将这个字符串值赋给变量my_name。传递给这个函数的字符串'>'导致屏幕上出现提示符>,以向用户指出程序在等待他输入内容。在你自己编写的程序中,可不向函数input()传递字符串;若直接调用input()函数,程序依然会等待用户输入,但不会显示任何提示。

提示符>和>>>

要修改程序运行时出现的提示符,可将相应的字符串传递给input()函数。调用input('>') 会将尖括号(>)作为提示符显示在屏幕上,这不同于Python交互式环境中出现的提示符>>>。在本书中,提示符>>>表示对Python交互式环境做出的响应,而提示符>表示对运行函数调用input('>')的程序做出的响应。作者选择使用提示符>是自己决定的,你在自己编写的程序中,可根据喜好使用任何提示符,或者根本不使用提示符。

可将函数调用input()视为一个表达式,其结果为用户输入的字符串。换言之,如果用户输入的是'Al',上述赋值语句将与my_name = 'Al'等效。

如果调用input()时出现类似于NameError: name 'Al' is not defined这样的错误消息,那是因为你在运行代码时使用的是Python 2,而不是Python 3。

1.6.4 问候语

在下面的print()函数调用中,括号内包含表达式'It is good to meet you, ' + my_name:

print('It is good to meet you, ' + my_name)

前面说过,表达式的结果都是单个值。如果存储在变量my_name中的值为'Al',那么这个表达式的结果将为'It is good to meet you, Al'。接下来,这个字符串值被传递给print(),而print()将把它显示在屏幕上。

1.6.5 函数len()

可向函数len()传递一个字符串值(或包含字符串的变量),而这个函数将返回一个整数,指出该字符串包含的字符数:

print('The length of your name is:')
print(len(my_name))

为确定这一点,请在交互式环境中输入如下代码:

>>> len('hello')
5
>>> len('My very energetic monster just scarfed nachos.')
46
>>> len('')
0

与这些示例表明的一样,len(my_name)的结果是一个整数。在这种情况下,我们说函数调用len()返回或输出一个整数值,并将这个整数值称为函数调用的返回值。接下来,将这个整数值传递给print(),以便将其显示在屏幕上。可向函数print()传递整数值或字符串值,但如果在交互式环境中输入下面的代码,将出现错误消息:

>>> print('I am ' + 29 + ' years old.') 
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    print('I am ' + 29 + ' years old.')
TypeError: can only concatenate str (not "int") to str

导致上述错误的罪魁祸首并非函数print()本身,而是传递给它的表达式。如果你在交互式环境中输入这个表达式,将出现同样的错误消息:

>>> 'I am ' + 29 + ' years old.'
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    'I am ' + 29 + ' years old.'
TypeError: can only concatenate str (not "int") to str

Python为何会显示上述错误消息呢?因为运算符+只能用来将两个数字相加或将两个字符串拼接起来。不能将整数和字符串相加,因为Python不允许这样做。要解决这个问题,可将这里的整数转换为字符串,这将在1.6.6节介绍。

1.6.6 函数str()、int()和float()

如果要将整数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(),再在input()等待你输入文本时输入101:

>>> spam = input() 
101
>>> spam
'101'

变量spam中存储的值不是整数101,而是字符串'101'。如果要使用变量spam存储的值来执行数学运算,可使用函数int()来获取其整数形式,再将结果作为这个变量的新值。如果变量spam的值为字符串'101',那么表达式int(spam)的结果将为整数值101,而赋值语句spam = int(spam)将与spam = 101等效:

>>> spam = int(spam)
>>> spam
101

现在,就可以将变量spam作为整数(而不是字符串)使用了:

>>> spam * 10 / 5
202.0

请注意,如果传递给int()的值不能转换为整数,Python将显示一条错误消息:

>>> int('99.99')
Traceback (most recent call last): 
  File "<python-input-0>", 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 "<python-input-0>", 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?') #要求用户提供其年龄。
my_age = input('>')
print('You will be ' + str(int(my_age) + 1) + ' in a year.')

变量my_age包含函数input()返回的值。因为函数input()总是返回一个字符串(即便用户输入的是数字亦如此),所以可使用代码int(my_age)将变量my_age中的字符串转换为整数值。然后,将这个整数值与1相加,如表达式int(my_age) + 1所示。

文本和数字之间的相等性

数字的字符串版本被认为完全不同于数字本身,但整数与相应的浮点数被认为是相等的:

>>> 42 == '42'
False
>>> 42 == 42.0
True
>>> 42.0 == 0042.000
True

Python为何做这样的区分呢?因为字符串为文本,而整数和浮点数都是数字。

相加的结果被传递给函数str(),即str(int(my_age) + 1)。接下来,将返回的字符串值与字符串'You will be '和' in a year.'拼接起来,形成一个更长的字符串。最后,将这个更长的字符串传递给函数print(),以便在屏幕上显示它。

假设用户输入并存储在my_age中的是字符串'4',上述执行步骤将类似于下面这样:

字符串'4'被转换为整数,以便能够将其与1相加。相加的结果为5。函数str()将结果转换为字符串,以便能够将其与第二个字符串('in a year.')拼接,以生成最终的消息。

1.6.7 函数type()

在Python中,并非只有整数、浮点数和字符串这3种数据类型。在学习编程的过程中,你还可能遇到其他数据类型。要确定值所属的数据类型,可将其传递给函数type()。例如,可在交互式环境中输入下面的代码:

>>> type(42)
<class 'int'>
>>> type(42.0)
<class 'float'>
>>> type('forty two')
<class 'str'>
>>> name = 'Zophie'
>>> type(name) # 变量name存储的值的数据类型为字符串
<class 'str'>
>>> type(len(name)) # 函数len()返回的是整数值
<class 'int'>

与其他所有函数调用一样,不仅可以将值传递给type(),还可将变量或表达式传递给它,以确定变量值或表达式结果的数据类型。函数type()也返回值,但尖括号意味着这些值并非合乎语法的Python代码;换言之,类似于spam = <class 'str'>这样的代码是无法运行的。

1.6.8 函数round()和abs()

下面来介绍另外两个Python函数,它们与函数len()一样,也接受一个参数并返回一个值。函数round()接受一个浮点数,并返回与之最接近的整数。请在交互式环境中输入下面的代码:

>>> round(3.14)
3
>>> round(7.7)
8
>>> round(-2.2)
-2

函数round()还接受第二个参数,这个参数是可选的,指定结果要包含多少位小数。请在交互式环境中输入下面的代码:

>>> round(3.14, 1)
3.1
>>> round(7.7777, 3)
7.778

当参数的小数部分为.5时,舍入行为有点奇怪。函数调用round(3.5)的结果为4(向上取整),而round(2.5)的结果为2(向下取整)。对于以.5结尾的数字,将被取整为与之最接近的偶数,这种方式被称为“银行家舍入”。

函数abs()接受一个数字参数,并返回该参数的绝对值。在数学中,绝对值被定义为与0的距离,但作者发现,将绝对值视为数字的正数形式更容易理解。请在交互式环境中输入下面的代码:

>>> abs(25)
25
>>> abs(-25)
25
>>> abs(-3.14)
3.14
>>> abs(0)
0

在本书后面,还将介绍Python自带的其他几个函数。由本节可知,可在交互式环境中尝试使用各种函数,以了解在输入不同的情况下,它们的行为有何不同。这是一种常用的学习新代码的方法。

1.7 计算机如何使用二进制数存储数据

有关Python代码就暂时介绍到这里。此时你可能认为,编程就像魔术一样神奇。计算机是如何将2 + 2转换为4的呢?对本书的读者来说,这个问题的答案过于复杂,这里只介绍幕后情况的一部分:计算时涉及的二进制数(由0和1组成的数字)。

在非法入侵计算机的电影桥段中,常常能够看到一系列的0和1在屏幕上滚动。这看起来神秘莫测,令人印象深刻。这些1和0到底是什么呢?答案是它们是二进制数。二进制是最简单的数制,在计算机硬件中可使用价格低廉的组件来实现。二进制也被称为以2为基数的数制,我们熟悉的以10为基数的数制能够表示的所有数字,二进制都能够表示。十进制使用10个数字:0~9。表1-4展示了前27个非负整数(0~26)的十进制和二进制表示。

表1-4 前27个非负整数的十进制和二进制表示

十进制

二进制

十进制

二进制

十进制

二进制

0

0

9

1001

18

10010

1

1

10

1010

19

10011

2

10

11

1011

20

10100

3

11

12

1100

21

10101

4

100

13

1101

22

10110

5

101

14

1110

23

10111

6

110

15

1111

24

11000

7

111

16

10000

25

11001

8

1000

17

10001

26

11010

这些数制类似于图1-3所示的机械式里程表。在每一位中,到达最大可能值后,都重置为0,同时将上一位加1。在十进制中,每位的最大可能值为9,而在二进制中,每位的最大可能值为1。有鉴于此,在十进制中,9后面的数字为10,而999后面的数字为1000。同理,在二进制中,1后面的数字为10,而111后面的数字为1000。然而,二进制值10表示的并非10,而是2;二进制数1000表示的并非1000,而是8。

图1-3 十进制机械式里程表(左)和二进制机械式里程表(右)

使用计算机硬件表示二进制数比表示十进制数更容易,因为需要表示的状态只有两种。例如,在蓝光光碟和DVD的表面,有平滑区域和凹坑,前者反射激光,而后者不反射;电路可以有通电和断电两种情形。这些硬件标准都能够表示两种不同的状态。相反,要制造高品质电子器件(即足够敏感、能够以可靠精度检测10种不同的电平),成本将非常高。使用简单电子器件时,成本更低,而两种二进制状态也更简单可靠。

这些二进制位被简称为“位”。1位可表示两个数字,而8位(1字节)可表示28(256)个数字:十进制数0~255(二进制数0~11 111 111)。同理,单个十进制位可表示10个数字(0~9),而8个十进制位可表示108(100 000 000)个数字(0~99 999 999)。在计算机中,文件大小以其占用的字节数来衡量。

1千字节(KB)为210(1 024)字节。

1兆字节(MB)为220(1 048 576)字节,即1024 KB。

1吉字节(GB)230(1 073 741 824)字节,即1024 MB。

1太字节(TB)为240(1 099 511 627 776字节),即1024 GB。

莎士比亚的《罗密欧与朱丽叶》包含的文本大约为135 KB;高分辨率照片为2~5 MB(随照片质量而异);电影为1~50 GB(随影片时长而异)。然而,在这些术语的含义方面,硬盘和闪存制造商明目张胆地撒谎。例如,将1 000 000 000 000(而不是1 099 511 627 776)字节称为1 TB,从而能够将9.09 TB的硬盘作为10 TB硬盘进行售卖。

使用1和0的二进制不仅能够表示任何整数,还能够表示任何形式的数据。例如,通过采用二进制补码,1字节可表示数字-128~127,而不是0~255;通过采用IEEE-754,可表示浮点数。

在计算机中,可以二进制数方式存储文本,方法是将每个字母、标点和符号都关联到一个不同的数字。用于将文本表示为数字的系统被称为编码系统,最常用的文本编码系统是UTF-8,在这种编码系统中,大写字母A由十进制数65(或8位二进制数01000001)表示,?(问号)由数字63表示,而数字字符7由数字55表示。对于字符串'Hello'被存储为数字72、101、108、108和111,因此存储在计算机中时,Hello呈现为如下位流:0100100001100101011011000110110001101111。

这看起来很像黑客电影中的场景!

对于每种形式的数据,为将其编码为数字,工程师们都需要发明相应的编码方式。对于照片和图像,可将其划分为由颜色方块(被称为像素)组成的二维网格;对于每个像素,都可使用3字节来表示其颜色的红、绿、蓝分量(有关图像数据,第21章将给出更详细的介绍)。例如,可使用数字255、0和255表示一个这样的像素:红色和蓝色分量为可能的最大值,而绿色分量为0(即紫色像素)。

声音由传播到人耳朵中的压缩空气波组成,被人类的大脑解读为听觉。可将这些波的强度和频率随时间的变化情况绘制为图形,再将图形上的数字转换为二进制数并存储到计算机中,之后计算机会控制扬声器来重现声音。这里简化了计算机音频的工作原理,但描绘了如何用数字来表示贝多芬第五交响曲。

众多图像数据和音频数据组合后便形成了视频,任何形式的信息都可编码为二进制数。当然,涉及的细节比这里介绍的要多得多,但在当今的信息时代,各种数据就是以这里介绍的方式用1和0表示的。

1.8 小结

你可以使用计算器来计算表达式的结果,也可以使用文字处理软件通过输入来拼接字符串,还可以通过复制并粘贴文本来轻松地将字符串重复多次。然而,表达式及其组成部分(运算符、变量和函数调用)是构成程序的基本构件,知道如何处理这些元素后,就能够让Python替你处理大量的数据。

你将发现,牢记本章介绍的各种运算符(数学运算符+、-、*、/、//、%和**,以及字符串运算符+和*)和3种数据类型(整数、浮点数和字符串)大有裨益。

另外,本章还介绍了一些函数,其中函数print()和input()用于处理简单的文本输出(输出到屏幕)和文本输入(来自键盘);函数len()接受一个字符串参数,并返回一个整数,指出作为参数的字符串包含多少个字符;函数str()、int()和float()分别返回传递给它们的值的字符串、整数和浮点数版本;函数round()返回通过舍入得到的整数,而函数abs()返回参数的绝对值。

第2章将介绍如何让Python根据它拥有的值就如下方面做出明智的决定:执行哪些代码、跳过哪些代码和反复执行哪些代码。这被称为流程控制,让你能够编写出能够做出明智决定的程序。

相关图书

DeepSeek原理与项目实战大模型部署、微调与应用开发
DeepSeek原理与项目实战大模型部署、微调与应用开发
软件工程3.0:大模型驱动的研发新范式
软件工程3.0:大模型驱动的研发新范式
图机器学习
图机器学习
Vibe Coding:AI 编程时代的认知重构
Vibe Coding:AI 编程时代的认知重构
大模型工程化:AI驱动下的数据体系
大模型工程化:AI驱动下的数据体系
Cursor与MCP快速入门:零基础开发智能体应用
Cursor与MCP快速入门:零基础开发智能体应用

相关文章

相关课程