原文:
zh.annas-archive.org/md5/97bc15629f1b51a0671040c56db61b92
译者:飞龙
前言
这个学习路径帮助你在 Python 的世界中感到舒适。它从对 Python 的全面和实用的介绍开始。你将很快开始在学习路径的第一部分编写程序。借助链表、二分搜索和排序算法的力量,你将轻松地创建复杂的数据结构,如图、栈和队列。在理解了协同继承之后,你将熟练地引发、处理和操纵异常。你将轻松地整合 Python 的面向对象和非面向对象的方面,并使用更高级的设计模式创建可维护的应用程序。一旦你掌握了核心主题,你将理解单元测试的乐趣,以及创建单元测试有多么容易。
通过这个学习路径,你将构建易于理解、调试并可用于不同应用的组件。
这个学习路径包括以下 Packt 产品的内容:
- 《学习 Python 编程-第二版》作者:法布里齐奥·罗马诺
- 《Python 数据结构和算法》作者:本杰明·巴卡
- 《Python 3 面向对象编程》作者:达斯蒂·菲利普斯
这本书适合谁
如果你相对新手,并希望使用 Python 编写脚本或程序来完成任务,或者如果你是其他语言的面向对象程序员,并希望在 Python 的世界中有所提升,那么这个学习路径适合你。虽然不是必需的,但具有编程和面向对象编程的基本知识会对你有所帮助。
这本书涵盖了什么
第一章《Python 的初步介绍》向你介绍了基本的编程概念。它指导你如何在计算机上运行 Python,并向你介绍了一些构造。
第二章《内置数据类型》向你介绍了 Python 的内置数据类型。Python 拥有非常丰富的本地数据类型,本章将为你介绍每种类型的描述和简短示例。
第三章《迭代和决策》教你如何通过检查条件、应用逻辑和执行循环来控制代码的流程。
第四章《函数,代码的构建块》教你如何编写函数。函数是重用代码、减少调试时间以及编写更好代码的关键。
第五章《文件和数据持久性》教你如何处理文件、流、数据交换格式和数据库等内容。
第六章《算法设计原则》涵盖了如何使用现有的 Python 数据结构构建具有特定功能的结构。一般来说,我们创建的数据结构需要符合一些原则。这些原则包括健壮性、适应性、可重用性和将结构与功能分离。我们将探讨迭代的作用,并介绍递归数据结构。
第七章《列表和指针结构》涵盖了链表,这是最常见的数据结构之一,通常用于实现其他结构,如栈和队列。在本章中,我们描述了它们的操作和实现。我们比较它们与数组的行为,并讨论了各自的相对优势和劣势。
第八章,“栈和队列”,讨论了这些线性数据结构的行为,并演示了一些实现。我们给出了典型应用的例子。
第九章,“树”,将讨论如何实现二叉树。树是许多最重要的高级数据结构的基础。我们将研究如何遍历树、检索和插入值。我们还将看看如何创建堆等结构。
第十章,“哈希和符号表”,描述了符号表,给出了一些典型的实现,并讨论了各种应用。我们将研究哈希的过程,给出哈希表的实现,并讨论各种设计考虑因素。
第十一章,“图和其他算法”,介绍了一些更专业的结构,包括图和空间结构。将数据表示为一组节点和顶点在许多应用中很方便,从中我们可以创建结构,如有向图和无向图。我们还将介绍一些其他结构和概念,如优先队列、堆和选择算法。
第十二章,“搜索”,讨论了最常见的搜索算法,并举例说明它们在各种数据结构中的使用。搜索数据结构是一项基本任务,有许多方法。
第十三章,“排序”,探讨了最常见的排序方法。这将包括冒泡排序、插入排序和选择排序。
第十四章,“选择算法”,涵盖了涉及查找统计数据的算法,例如列表中的最小值、最大值或中位数元素。有许多方法,其中最常见的方法之一是首先应用排序操作。其他方法包括分区和线性选择。
第十五章,“面向对象设计”,涵盖了重要的面向对象概念。主要涉及抽象、类、封装和继承等术语。我们还简要介绍了使用 UML 来建模我们的类和对象。
第十六章,“Python 中的对象”,讨论了在 Python 中使用的类和对象。我们将了解 Python 对象的属性和行为,以及类组织成包和模块。最后,我们将看到如何保护我们的数据。
第十七章,“当对象相似时”,更深入地介绍了继承。它涵盖了多重继承,并向我们展示了如何扩展内置。本章还涵盖了多态性和鸭子类型在 Python 中的工作原理。
第十八章,“意料之外”,深入研究了异常和异常处理。我们将学习如何创建自己的异常,以及如何利用异常来控制程序流程。
第十九章,“何时使用面向对象编程”,涉及创建和使用对象。我们将看到如何使用属性包装数据并限制数据访问。本章还讨论了 DRY 原则以及如何避免重复代码。
第二十章,“Python 面向对象的快捷方式”,顾名思义,涉及 Python 中的节省时间的方法。我们将研究许多有用的内置函数,例如使用默认参数进行方法重载。我们还将看到函数本身是对象,以及这如何有用。
第二十一章,迭代器模式,介绍了设计模式的概念,并涵盖了 Python 对迭代器模式的标志性实现。我们将学习列表、集合和字典推导式。我们还将揭开生成器和协程的神秘面纱。
第二十二章,Python 设计模式 I,涵盖了几种设计模式,包括装饰器、观察者、策略、状态、单例和模板模式。每种模式都有适当的示例和 Python 中的程序实现。
第二十三章,Python 设计模式 II,以适配器、外观、享元、命令、抽象和组合模式结束了我们对设计模式的讨论。提供了更多关于惯用 Python 代码与规范实现的示例。
第二十四章,测试面向对象的程序,从为什么在 Python 应用程序中进行测试如此重要开始。它专注于测试驱动开发,并介绍了两种不同的测试套件:unittest 和 py.test。最后,它讨论了模拟测试对象和代码覆盖。
为了充分利用本书
本书中的代码将需要您运行 Python 2.7.x 或更高版本。Python 的默认交互环境也可以用于运行代码片段。
本书中的一些示例依赖于不随 Python 一起发布的第三方库。它们在使用时会在书中介绍,因此您不需要提前安装它们。
下载示例代码文件
您可以从www.packt.com的帐户中下载本书的示例代码文件。如果您在其他地方购买了本书,可以访问www.packt.com/support并注册,文件将直接通过电子邮件发送给您。
您可以按照以下步骤下载代码文件:
- 登录或注册www.packt.com。
- 选择“支持”选项卡。
- 单击“代码下载和勘误”。
- 在搜索框中输入书名,然后按照屏幕上的说明操作。
下载文件后,请确保使用以下最新版本解压或提取文件夹:
- WinRAR/7-Zip for Windows
- Zipeg/iZip/UnRarX for Mac
- 7-Zip/PeaZip for Linux
该书的代码包也托管在 GitHub 上,网址为github.com/PacktPublishing/Getting-Started-with-Python
。如果代码有更新,将在现有的 GitHub 存储库上进行更新。
我们还有其他代码包,来自我们丰富的图书和视频目录,可在**github.com/PacktPublishing/
**上查看!
使用的约定
本书中使用了一些文本约定。
CodeInText
:表示文本中的代码词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 句柄。例如:“if
、else
和elif
语句控制语句的条件执行。”
代码块设置如下:
a=10; b=20 def my_function():
当我们希望引起您对代码块的特定部分的注意时,相关行或项目将以粗体显示:
if "WARNING" in l: **yield l.replace("\tWARNING", "")**
任何命令行输入或输出都是这样写的:
>>> print(warnings_filter([]))
粗体:表示新术语、重要单词或屏幕上看到的单词。例如,菜单或对话框中的单词会以这种方式出现在文本中。例如:“然后,如果标签与颜色匹配,您必须手动点击是或否。”
警告或重要说明会这样显示。提示和技巧会这样显示。
第一章:Python 的初步介绍
“授人以鱼不如授人以渔。”- 中国谚语
根据维基百科的说法,计算机编程是:
“…从计算问题的原始表述到可执行的计算机程序的过程。编程涉及活动,如分析,开发理解,生成算法,验证算法的要求,包括它们的正确性和资源消耗,以及在目标编程语言中实现(通常称为编码)算法。”
简而言之,编码就是用计算机能理解的语言告诉计算机做某事。
计算机是非常强大的工具,但不幸的是,它们无法自行思考。它们需要被告知一切:如何执行任务,如何评估条件以决定要遵循哪条路径,如何处理来自设备的数据,比如网络或磁盘,以及在发生意外情况时如何做出反应,比如,某物坏了或丢失了。
你可以用许多不同的风格和语言编写代码。难吗?我会说是和不是。这有点像写作。每个人都可以学会写作,你也可以。但是,如果你想成为一名诗人呢?那么仅仅写作是不够的。你必须获得一整套其他技能,这需要更长时间和更大的努力。
最终,一切都取决于你想走多远。编码不仅仅是将一些有效的指令组合在一起。它远不止如此!
良好的代码是简短、快速、优雅、易于阅读和理解、简单、易于修改和扩展、易于扩展和重构、易于测试。要能够同时具备所有这些品质的代码需要时间,但好消息是,通过阅读这本书,你正在迈出迈向这个目标的第一步。我毫无疑问你能做到。任何人都可以;事实上,我们都在不知不觉中一直在编程。
你想要一个例子吗?
假设你想泡速溶咖啡。你需要准备一个杯子,速溶咖啡罐,一把茶匙,水和水壶。即使你没有意识到,你正在评估大量的数据。你要确保水壶里有水,水壶已插好电,杯子干净,并且咖啡罐里有足够的咖啡。然后,你烧开水,也许在此期间,你把一些咖啡放进杯子里。当水准备好时,你把它倒进杯子里,然后搅拌。
那么,这就是编程吗?
好吧,我们收集了资源(水壶,咖啡,水,茶匙和杯子),并验证了一些关于它们的条件(水壶已插好电,杯子干净,并且有足够的咖啡)。然后我们开始了两个动作(烧水和把咖啡放进杯子里),当它们都完成时,我们最终通过把水倒进杯子里并搅拌来结束了这个过程。
你能看到吗?我刚刚描述了一个咖啡程序的高级功能。这并不难,因为这就是大脑整天在做的事情:评估条件,决定采取行动,执行任务,重复其中一些,并在某个时候停下来。清理物品,把它们放回去,等等。
现在你需要学会如何分解你在现实生活中自动完成的所有这些动作,以便计算机实际上能够理解它们。而且你还需要学习一种语言,来指导它。
所以这本书就是为此而写的。我会告诉你如何做,我会尝试通过许多简单但专注的例子来做到这一点(这是我最喜欢的一种)。
在这一章中,我们将涵盖以下内容:
- Python 的特点和生态系统
- 关于如何开始并运行 Python 和虚拟环境的指南
- 如何运行 Python 程序
- 如何组织 Python 代码和 Python 的执行模型
一个合适的介绍
我喜欢在教编码时引用现实世界;我相信这有助于人们更好地理解概念。然而,现在是时候更严谨地从技术角度看待编码是什么了。
当我们编写代码时,我们在指示计算机要做的事情。行动发生在哪里?在很多地方:计算机内存、硬盘、网络电缆、CPU 等等。这是一个完整的世界,大部分时间是真实世界的一个子集的表示。
如果你写了一个允许人们在线购买服装的软件,你将不得不在程序的范围内代表真实的人、真实的服装、真实的品牌、尺寸等等。
为了做到这一点,你需要在你编写的程序中创建和处理对象。一个人可以是一个对象。一辆车是一个对象。一双袜子是一个对象。幸运的是,Python 非常了解对象。
任何对象具有的两个主要特征是属性和方法。让我们以一个人的对象为例。在计算机程序中,你通常将人表示为顾客或员工。你存储在他们身上的属性是姓名、社会安全号码、年龄、是否有驾照、电子邮件、性别等等。在计算机程序中,你存储了所有你需要的数据,以便使用对象来服务你的目的。如果你正在编写一个销售服装的网站,你可能还想存储顾客的身高、体重以及其他尺寸,以便为他们推荐合适的服装。因此,属性是对象的特征。我们经常使用它们:你能把那支笔递给我吗?—哪一支?—黑色的那支。在这里,我们使用了笔的黑色属性来识别它(很可能是在蓝色和红色中)。
方法是对象可以做的事情。作为一个人,我有诸如说话、走路、睡觉、醒来、吃饭、做梦、写、读等方法。我能做的所有事情都可以看作是代表我的对象的方法。
现在你知道了对象是什么,它们公开了可以运行的方法和可以检查的属性,你已经准备好开始编码了。实际上,编码就是简单地管理我们在软件中再现的世界子集中的那些对象。你可以随意创建、使用、重用和删除对象。
根据官方 Python 文档的数据模型章节(docs.python.org/3/reference/datamodel.html
):
“对象是 Python 对数据的抽象。Python 程序中的所有数据都由对象或对象之间的关系表示。”
我们将在后面的章节中更仔细地看 Python 对象。目前,我们需要知道的是 Python 中的每个对象都有一个 ID(或身份)、一个类型和一个值。
一旦创建,对象的 ID 就永远不会改变。这是它的唯一标识符,并且在幕后被 Python 用来在我们想要使用它时检索对象。
类型也永远不会改变。类型告诉对象支持哪些操作以及可以分配给它的可能值。
我们将在第二章中看到 Python 最重要的数据类型,内置数据类型。
值可以改变,也可以不改变。如果可以改变,对象被称为可变,而当它不能改变时,对象被称为不可变。
我们如何使用一个对象?当然是给它一个名字!当你给一个对象一个名字,然后你可以使用这个名字来检索对象并使用它。
在更一般的意义上,诸如数字、字符串(文本)、集合等对象都与一个名称相关联。通常,我们说这个名称是变量的名称。你可以把变量看作是一个盒子,你可以用它来存储数据。
所以,你拥有了所有你需要的对象;现在呢?好吧,我们需要使用它们,对吧?我们可能想要通过网络连接发送它们,或者将它们存储在数据库中。也许在网页上显示它们,或者将它们写入文件。为了做到这一点,我们需要对用户填写表单、按下按钮、打开网页并执行搜索做出反应。我们通过运行我们的代码来做出反应,评估条件以选择执行哪些部分,多少次,以及在什么情况下。
为了做到所有这些,基本上我们需要一种语言。这就是 Python 的用途。在本书中,我们将一起使用 Python 来指导计算机为我们做一些事情。
现在,够了这些理论的东西;让我们开始吧。
进入 Python
Python 是 Guido Van Rossum 的奇迹创造,他是一位荷兰计算机科学家和数学家,决定在 1989 年圣诞节期间向世界赠送他正在玩耍的项目。这种语言大约在 1991 年左右出现在公众面前,从那时起,它已经发展成为全球范围内使用的主要编程语言之一。
我 7 岁开始编程,用的是 Commodore VIC-20,后来换成了它的大哥 Commodore 64。它的语言是 BASIC。后来,我接触了 Pascal、Assembly、C、C++、Java、JavaScript、Visual Basic、PHP、ASP、ASP .NET、C#,以及其他一些我甚至都记不起来的小语言,但直到我接触到 Python,我才有了那种在商店里找到合适的沙发时的感觉。当你的所有身体部位都在喊着,“买这个!这个对我们来说完美!”
我大约花了一天时间适应它。它的语法与我习惯的有点不同,但在克服了最初的不适感之后(就像穿上新鞋一样),我就深深地爱上了它。让我们看看为什么。
关于 Python
在我们深入了解细节之前,让我们了解一下为什么有人会想要使用 Python(我建议你阅读维基百科上的 Python 页面,以获得更详细的介绍)。
在我看来,Python 体现了以下特质。
可移植性
Python 可以在任何地方运行,将程序从 Linux 移植到 Windows 或 Mac 通常只是修复路径和设置的问题。Python 被设计用于可移植性,并且它会处理特定操作系统(OS)的怪癖,这些接口会让你免于编写针对特定平台的代码的痛苦。
连贯性
Python 非常逻辑和连贯。你可以看出它是由一位杰出的计算机科学家设计的。大多数时候,如果你不知道一个方法的调用方式,你可以猜出来。
你现在可能没有意识到这一点有多重要,特别是如果你还处在起步阶段,但这是一个重要的特性。这意味着你的头脑中没有那么多杂乱,也不需要在编码时浏览文档,也不需要在大脑中进行映射。
开发者生产力
根据 Mark Lutz(《学习 Python,第 5 版》,O’Reilly Media)的说法,Python 程序通常只有等效的 Java 或 C++代码的五分之一到三分之一大小。这意味着工作可以更快地完成。更快是好的。更快意味着市场上更快的反应。更少的代码不仅意味着写的代码更少,而且意味着阅读的代码更少(专业程序员阅读的比写的要多得多),维护的代码更少,调试的代码更少,重构的代码更少。
另一个重要的方面是,Python 可以在不需要冗长和耗时的编译和链接步骤的情况下运行,因此你不必等待看到你的工作成果。
一个广泛的库
Python 拥有一个非常广泛的标准库(据说它是带有内置电池)。如果这还不够,全世界的 Python 社区维护着一系列第三方库,专门针对特定需求定制,你可以在Python Package Index(PyPI)上自由获取。当你编写 Python 代码时,你意识到你需要某个特定功能时,在大多数情况下,至少有一个库已经为你实现了该功能。
软件质量
Python 非常注重可读性、连贯性和质量。语言的统一性使得它具有很高的可读性,这在当今编码更多是集体努力而不是个人努力的情况下至关重要。Python 的另一个重要方面是其固有的多范式特性。你可以将其用作脚本语言,但也可以利用面向对象、命令式和函数式编程风格。它是多才多艺的。
软件集成
另一个重要的方面是 Python 可以扩展和集成许多其他语言,这意味着即使一家公司使用不同的语言作为他们的主流工具,Python 也可以作为一个粘合剂在某种程度上连接需要相互通信的复杂应用程序。这是一个比较高级的话题,但在现实世界中,这个特性非常重要。
满意和享受
最后但并非最不重要的是,这很有趣!使用 Python 很有趣。我可以编写 8 小时的代码,离开办公室时感到快乐和满足,对于其他使用不提供同样数量精心设计的数据结构和构造的编码人员所遭受的挣扎毫不知情。毫无疑问,Python 让编码变得有趣。而有趣则促进了动力和生产力。
有什么缺点吗?
也许,人们在 Python 中唯一可能找到的缺点(不是由于个人偏好)是它的执行速度。通常情况下,Python 比它的编译兄弟慢。Python 的标准实现在运行应用程序时会生成源代码的编译版本,称为字节码(扩展名为.pyc
),然后由 Python 解释器运行。这种方法的优势是可移植性,但由于 Python 没有像其他语言那样编译到机器级别,我们需要付出减速的代价。
然而,Python 的速度在今天很少是一个问题,因此它被广泛使用,尽管有这个次优特性。在现实生活中,硬件成本不再是一个问题,通常很容易通过并行化任务来提高速度。此外,许多程序花费大部分时间等待 IO 操作完成;因此,原始执行速度通常是整体性能的次要因素。不过,当涉及到大量计算时,人们可以切换到更快的 Python 实现,比如 PyPy,通过实现先进的编译技术,它提供了平均五倍的加速(参考pypy.org/
)。
在进行数据科学时,你很可能会发现,你使用的 Python 库,如Pandas和NumPy,由于它们的实现方式,实现了本地速度。
如果这还不足以说服你,你可以考虑 Python 已被用于驱动 Spotify 和 Instagram 等服务的后端,其中性能是一个问题。尽管如此,Python 已经完全胜任了它的工作。
今天谁在使用 Python?
还不够说服?让我们简要看一下今天正在使用 Python 的公司:谷歌、YouTube、Dropbox、雅虎、Zope 公司、工业光与魔法、华特迪士尼特效动画、Blender 3D、皮克斯、NASA、NSA、红帽、诺基亚、IBM、Netflix、Yelp、英特尔、思科、惠普、高通和摩根大通,仅举几例。
甚至像战地 2、文明 4和QuArK这样的游戏都是用 Python 实现的。
Python 在许多不同的环境中使用,如系统编程、Web 编程、GUI 应用程序、游戏和机器人技术、快速原型设计、系统集成、数据科学、数据库应用等。一些知名的大学也已经将 Python 作为他们计算机科学课程的主要语言。
设置环境
在谈论如何在你的系统上安装 Python 之前,让我告诉你我在本书中将使用的 Python 版本。
Python 2 与 Python 3
Python 有两个主要版本:Python 2 是过去,Python 3 是现在。这两个版本虽然非常相似,但在某些方面是不兼容的。
在现实世界中,Python 2 实际上离过去还相当遥远。简而言之,尽管 Python 3 自 2008 年以来就已经发布,但从版本 2 过渡到版本 3 的阶段仍然远未结束。这主要是因为 Python 2 在工业界被广泛使用,当然,公司并不急于仅仅为了更新而更新他们的系统,遵循“如果它没坏,就不要修理”的理念。你可以在网络上阅读关于这两个版本之间过渡的所有信息。
另一个妨碍过渡的问题是第三方库的可用性。通常,Python 项目依赖于数十个外部库,当你开始一个新项目时,你需要确保已经有一个兼容 Version-3 的库来满足任何可能出现的业务需求。如果不是这样,那么在 Python 3 中启动一个全新的项目意味着引入潜在的风险,而许多公司并不愿意冒这种风险。
在撰写本文时,大多数最广泛使用的库已经移植到 Python 3,并且对于大多数情况来说,在 Python 3 中启动项目是相当安全的。许多库已经重写,以便与两个版本兼容,主要利用了six
库的功能(名称来源于 2 x 3 的乘法,因为从版本 2 到 3 的移植),它有助于根据使用的版本进行内省和行为调整。根据 PEP 373(legacy.python.org/dev/peps/pep-0373/
),Python 2.7 的生命周期结束(EOL)已经设定为 2020 年,不会有 Python 2.8,因此对于在 Python 2 中运行项目的公司来说,现在是需要开始制定升级策略并在太迟之前转移到 Python 3 的时候了。
在我的电脑上(MacBook Pro),这是我拥有的最新 Python 版本:
>>> import sys >>> print(sys.version) 3.7.0a3 (default, Jan 27 2018, 00:46:45) [Clang 9.0.0 (clang-900.0.39.2)]
因此,你可以看到这个版本是 Python 3.7 的 alpha 版本,将于 2018 年 6 月发布。前面的文本是我在控制台中输入的一小段 Python 代码。我们稍后会谈论它。
本书中的所有示例都将使用 Python 3.7 运行。尽管目前最终版本可能与我所拥有的略有不同,但我会确保所有的代码和示例在书籍出版时都是最新的 3.7 版本。
一些代码也可以在 Python 2.7 中运行,要么就是原样,要么稍作调整,但在这个时候,我认为最好先学习 Python 3,然后再了解它与 Python 2 的区别,而不是反过来。
不过,不要担心这个版本的问题;实际上并不是那么大的问题。
安装 Python
我从来没有真正理解为什么书中需要有一个设置部分,不管你需要设置什么。大多数情况下,作者写下指示的时间和你实际尝试它们的时间之间已经过去了几个月。如果你幸运的话。一旦版本发生变化,书中描述的方法可能就不再奏效了。幸运的是,现在我们有了网络,所以为了帮助你启动和运行,我只会给你一些指引和目标。
我知道大多数读者可能更喜欢在书中获得指导。但我怀疑这是否会让他们的生活变得更容易,因为我坚信,如果你想开始学习 Python,你必须付出最初的努力,以熟悉这个生态系统。这非常重要,它将增强你面对接下来章节中的材料的信心。如果遇到困难,请记住,谷歌是你的朋友。
设置 Python 解释器
首先,让我们谈谈你的操作系统。Python 已经完全集成,并且很可能已经安装在几乎每个 Linux 发行版中。如果你使用 macOS,很可能 Python 也已经安装好了(但可能只有 Python 2.7),而如果你使用 Windows,你可能需要安装它。
获取 Python 和你需要的库并使其运行需要一些技巧。Linux 和 macOS 似乎是最适合 Python 程序员的用户友好操作系统;而 Windows 则需要更大的努力。
我的当前系统是 MacBook Pro,这也是我在整本书中将使用的系统,搭配 Python 3.7。
你要开始的地方是官方 Python 网站:www.python.org
。这个网站托管了官方 Python 文档和许多其他资源,你会发现非常有用。花点时间去探索一下。
另一个关于 Python 及其生态系统的优秀、富有资源的网站是docs.python-guide.org
。你可以找到使用不同方法在不同操作系统上设置 Python 的说明。
找到下载部分,选择适合你操作系统的安装程序。如果你使用 Windows,在运行安装程序时,请确保勾选“安装 pip”选项(实际上,我建议进行完整安装,以确保安装程序包含的所有组件都安装了)。我们稍后会讨论pip
。
现在 Python 已经安装在你的系统中,目标是能够打开控制台并通过键入python
运行 Python 交互式 shell。
请注意,我通常简称Python 交互式 shell为Python 控制台。
在 Windows 中打开控制台,转到“开始”菜单,选择“运行”,然后键入cmd
。如果在本书的示例中遇到类似权限问题的情况,请确保以管理员权限运行控制台。
在 macOS X 上,你可以通过转到“应用程序”|“实用工具”|“终端”来启动终端。
如果你使用 Linux,你对控制台的了解就足够了。
我将使用术语控制台来交替指代 Linux 控制台、Windows 命令提示符和 Macintosh 终端。我还将用 Linux 默认格式指示命令行提示符,就像这样:
$ sudo apt-get update
如果你对此不熟悉,请花些时间学习控制台的基础知识。简而言之,在$
符号后,通常会有一个你需要输入的指令。注意大小写和空格,它们非常重要。
无论你打开哪个控制台,都在提示符处键入python
,确保 Python 交互式 shell 显示出来。键入exit()
退出。请记住,如果你的操作系统预装了 Python 2.*,可能需要指定python3
。
这大致是你运行 Python 时应该看到的情况(根据版本和操作系统的不同,细节可能会有所变化):
$ python3.7 Python 3.7.0a3 (default, Jan 27 2018, 00:46:45) [Clang 9.0.0 (clang-900.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>>
现在 Python 已经设置好,你可以运行它了,是时候确保你还有另一个工具,这个工具将是跟随本书示例不可或缺的:virtualenv。
关于 virtualenv
正如你可能已经猜到的那样,virtualenv关乎虚拟环境。让我通过一个简单的例子来解释它们是什么,为什么我们需要它们。
你在系统上安装了 Python,并开始为 X 客户工作。你创建了一个项目文件夹并开始编码。在此过程中,你还安装了一些库,例如 Django 框架。假设你为 X 项目安装的 Django 版本是 1.7.1。
现在,你的网站做得很好,你又得到了另一个客户 Y。她希望你为她建立另一个网站,所以你开始了 Y 项目,但在此过程中,你需要再次安装 Django。唯一的问题是现在 Django 的版本是 1.8,你不能在系统上安装它,因为这会替换你为 X 项目安装的版本。你不想冒险引入不兼容的问题,所以你有两个选择:要么你继续使用你当前机器上的版本,要么你升级它,并确保第一个项目仍然能够正确地使用新版本。
说实话,这些选项都不是很吸引人,对吧?绝对不是。所以,这里有解决方案:virtualenv!
virtualenv 是一个允许你创建虚拟环境的工具。换句话说,它是一个用于创建隔离的 Python 环境的工具,每个环境都是一个包含所有必要可执行文件的文件夹,以便使用 Python 项目所需的包(暂时将包视为库)。
所以你为 X 项目创建一个虚拟环境,安装所有依赖项,然后为 Y 项目创建一个虚拟环境,安装所有依赖项,而不用担心,因为你安装的每个库最终都会在适当的虚拟环境范围内。在我们的例子中,X 项目将使用 Django 1.7.1,而 Y 项目将使用 Django 1.8。
绝对不能直接在系统级别安装库非常重要。例如,Linux 依赖于 Python 执行许多不同的任务和操作,如果你在系统安装的 Python 上进行操作,就会有破坏整个系统完整性的风险(猜猜这是发生在谁身上的…)。所以把这当作一条规则,就像睡前刷牙一样重要:每次开始新项目时,一定要创建虚拟环境。
要在系统上安装 virtualenv,有几种不同的方法。例如,在基于 Debian 的 Linux 发行版上,你可以使用以下命令安装:
$ sudo apt-get install python-virtualenv
可能最简单的方法是按照 virtualenv 官方网站上的说明进行操作:virtualenv.pypa.io
。
你会发现,安装 virtualenv 最常见的方法之一是使用pip
,这是一个用于安装和管理用 Python 编写的软件包的软件包管理系统。
从 Python 3.5 开始,创建虚拟环境的建议方式是使用venv
模块。更多信息请参阅官方文档。然而,在撰写本文时,virtualenv 仍然是创建虚拟环境最常用的工具。
你的第一个虚拟环境
创建虚拟环境非常容易,但根据系统配置和想要虚拟环境运行的 Python 版本,你需要正确运行命令。另一件你需要做的事情是激活虚拟环境。激活虚拟环境基本上是在后台进行一些路径操作,这样当你调用 Python 解释器时,实际上是调用激活的虚拟环境,而不是系统的。
我将在我的 Macintosh 控制台上展示一个完整的示例。我们将:
- 在你的项目根目录下创建一个名为
learn.pp
的文件夹(在我的情况下是一个名为srv
的文件夹,在我的主目录下)。请根据你在计算机上喜欢的设置调整路径。 - 在
learn.pp
文件夹中,我们将创建一个名为learnpp
的虚拟环境。
一些开发人员更喜欢使用相同的名称来称呼所有虚拟环境(例如,.venv
)。这样他们就可以通过知道项目所在的名称来运行脚本。在 Linux/macOS 中,以点开头的名称会使文件或文件夹变得不可见。
- 创建虚拟环境后,我们将激活它。在 Linux、macOS 和 Windows 之间的方法略有不同。
- 然后,我们将确保我们正在运行所需的 Python 版本(3.7.*),通过运行 Python 交互式 shell。
- 最后,我们将使用
deactivate
命令来停用虚拟环境。
这五个简单的步骤将向您展示开始和使用项目所需做的一切。
以下是这些步骤可能看起来的一个示例(请注意,根据您的操作系统、Python 版本等,可能会得到略有不同的结果)在 macOS 上(以#
开头的命令是注释,空格是为了可读性引入的,⇢
表示由于空间不足而换行):
fabmp:srv fab$ # step 1 - create folder fabmp:srv fab$ mkdir learn.pp fabmp:srv fab$ cd learn.pp fabmp:learn.pp fab$ # step 2 - create virtual environment fabmp:learn.pp fab$ which python3.7 /Users/fab/.pyenv/shims/python3.7 fabmp:learn.pp fab$ virtualenv -p ⇢ /Users/fab/.pyenv/shims/python3.7 learnpp Running virtualenv with interpreter /Users/fab/.pyenv/shims/python3.7 Using base prefix '/Users/fab/.pyenv/versions/3.7.0a3' New python executable in /Users/fab/srv/learn.pp/learnpp/bin/python3.7 Also creating executable in /Users/fab/srv/learn.pp/learnpp/bin/python Installing setuptools, pip, wheel...done. fabmp:learn.pp fab$ # step 3 - activate virtual environment fabmp:learn.pp fab$ source learnpp/bin/activate (learnpp) fabmp:learn.pp fab$ # step 4 - verify which python (learnpp) fabmp:learn.pp fab$ which python /Users/fab/srv/learn.pp/learnpp/bin/python (learnpp) fabmp:learn.pp fab$ python Python 3.7.0a3 (default, Jan 27 2018, 00:46:45) [Clang 9.0.0 (clang-900.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> exit() (learnpp) fabmp:learn.pp fab$ # step 5 - deactivate (learnpp) fabmp:learn.pp fab$ deactivate fabmp:learn.pp fab$
请注意,我不得不明确告诉 virtualenv 使用 Python 3.7 解释器,因为在我的系统上 Python 2.7 是默认的。如果我没有这样做,我将得到一个带有 Python 2.7 而不是 Python 3.7 的虚拟环境。
你可以将第 2 步的两条指令合并成一条命令,就像这样:
$ virtualenv -p $( which python3.7 ) learnpp
在这种情况下,我选择明确详细,以帮助您理解每个步骤。
另一件需要注意的事情是,为了激活虚拟环境,我们需要运行/bin/activate
脚本,这需要被源化。当脚本被源化时,意味着它在当前 shell 中执行,因此其效果会在执行后持续存在。这非常重要。还要注意,在我们激活虚拟环境后,提示符会发生变化,左边会显示其名称(在我们停用它时会消失)。在 Linux 上,步骤是相同的,所以我不会在这里重复。在 Windows 上,事情略有不同,但概念是相同的。请参考官方 virtualenv 网站获取指导。
在这一点上,您应该能够创建和激活一个虚拟环境。请尝试创建另一个虚拟环境,而无需我的指导。熟悉这个过程,因为这是您将始终在做的事情:我们永远不会在系统范围内使用 Python,记住吗?这非常重要。
所以,一旦搭建好,我们就准备好更多地谈谈 Python 以及如何使用它。在我们开始之前,让我稍微谈谈控制台。
你的朋友,控制台
在这个 GUI 和触摸屏设备的时代,当一切都只是一个点击之遥时,不得不求助于控制台这样的工具似乎有点荒谬。
但事实是,每当你把右手(或者如果你是左撇子,是左手)从键盘上移开,去抓鼠标并将光标移动到你想点击的位置时,你都会浪费时间。用控制台完成任务,尽管可能有些违反直觉,但会提高生产力和速度。我知道,你必须相信我。
速度和生产力很重要,个人而言,我对鼠标没有任何意见,但还有另一个非常好的理由,你可能希望熟悉控制台:当你开发的代码最终部署到服务器上时,控制台可能是唯一可用的工具。如果你和它交朋友,我向你保证,在最重要的时候你永远不会迷失方向(通常是在网站宕机时,你需要迅速调查发生了什么)。
所以这真的取决于你。如果你还没有决定,请给我一点怀疑的好处,试一试。这比你想象的要容易,你永远不会后悔。没有什么比一个优秀的开发者因为习惯了自己定制的工具而在 SSH 连接到服务器中迷失更可悲的了。
现在,让我们回到 Python。
如何运行 Python 程序
有几种不同的方法可以运行 Python 程序。
运行 Python 脚本
Python 可以用作脚本语言。事实上,它总是非常有用的。脚本是文件(通常很小),通常用来执行一些任务。许多开发人员最终都会拥有自己的工具库,当他们需要执行任务时就会使用。例如,你可以有脚本来解析数据格式并将其呈现为另一种不同的格式。或者你可以使用脚本来处理文件和文件夹。你可以创建或修改配置文件,等等。从技术上讲,几乎没有什么是不能在脚本中完成的。
在服务器上定时运行脚本是非常常见的。例如,如果你的网站数据库每 24 小时需要清理一次(例如,存储用户会话的表,这些会话很快就会过期,但不会自动清理),你可以设置一个 Cron 作业,每天凌晨 3 点运行你的脚本。
根据维基百科,软件实用程序 Cron 是 Unix 类计算机操作系统中基于时间的作业调度程序。设置和维护软件环境的人使用 Cron 定期安排作业(命令或 shell 脚本)在固定的时间、日期或间隔运行。
运行 Python 交互式 shell
另一种运行 Python 的方法是调用交互式 shell。这是我们在控制台命令行中输入 python
时已经看到的东西。
所以,打开控制台,激活你的虚拟环境(现在应该已经成为你的第二天性了,对吧?),然后输入 python
。你会看到几行文字,应该是这样的:
$ python Python 3.7.0a3 (default, Jan 27 2018, 00:46:45) [Clang 9.0.0 (clang-900.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>>
那些 >>>
是 shell 的提示符。它们告诉你 Python 正在等待你输入。如果你输入一个简单的指令,一个适合一行的东西,那就是你会看到的。然而,如果你输入需要多于一行代码的东西,shell 会把提示符改成 ...
,给你一个视觉线索,告诉你正在输入一个多行语句(或者任何需要多于一行代码的东西)。
来吧,试一试;让我们做一些基本的数学:
>>> 2 + 4 6 >>> 10 / 4 2.5 >>> 2 ** 1024
179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216
最后的操作向你展示了一些不可思议的东西。我们将2
的1024
次方,Python 毫无困难地处理了这个任务。试着在 Java、C++或 C#中做这个操作。除非你使用特殊的库来处理这样大的数字,否则是行不通的。
我每天都使用交互式 shell。它非常有用,可以快速调试,例如,检查数据结构是否支持某个操作。或者检查或运行一段代码。
当你使用 Django(一个 Web 框架)时,交互式 shell 与之相结合,允许你通过框架工具来检查数据库中的数据,以及其他许多事情。你会发现交互式 shell 很快会成为你在这段旅程中最亲密的朋友之一。
另一种解决方案,以更好的图形布局呈现,是使用集成开发环境(IDLE)。这是一个相当简单的集成开发环境,主要面向初学者。它比你在控制台中得到的裸交互式 shell 具有稍微更多的功能,所以你可能想要探索一下。它在 Windows Python 安装程序中免费提供,你也可以轻松地在任何其他系统中安装它。你可以在 Python 网站上找到有关它的信息。
Guido Van Rossum 将 Python 命名为英国喜剧团体 Monty Python,因此有传言称 IDLE 的名称是为了纪念 Monty Python 的创始成员之一 Eric Idle 而选择的。
将 Python 作为服务运行
除了作为脚本运行之外,在 shell 的边界内,Python 还可以编码并作为应用程序运行。我们将在整本书中看到许多关于这种模式的例子。当我们谈论 Python 代码是如何组织和运行的时候,我们将更多地了解它。
将 Python 作为 GUI 应用程序运行
Python 也可以作为图形用户界面(GUI)运行。有几个可用的框架,其中一些是跨平台的,另一些是特定于平台的。
在其他 GUI 框架中,我们发现以下是最广泛使用的:
- PyQt
- Tkinter
- wxPython
- PyGTK
详细描述它们超出了本书的范围,但您可以在 Python 网站上找到所有您需要的信息(docs.python.org/3/faq/gui.html
),在*Python 存在哪些平台无关的 GUI 工具包?*部分。如果您正在寻找 GUI,请记住根据一些原则选择您想要的。确保它们:
- 提供您可能需要开发项目的所有功能
- 在您可能需要支持的所有平台上运行
- 依靠尽可能广泛和活跃的社区
- 包装图形驱动程序/工具,您可以轻松安装/访问
Python 代码是如何组织的?
让我们谈一下 Python 代码是如何组织的。在本节中,我们将更深入地探讨一些技术名称和概念。
从基础知识开始,Python 代码是如何组织的?当然,您将代码写入文件中。当您使用扩展名.py
保存文件时,该文件被称为 Python 模块。
如果您使用的是 Windows 或 macOS,通常会向用户隐藏文件扩展名,请确保更改配置,以便您可以看到文件的完整名称。这不是严格的要求,而是一个建议。
将所有软件所需的代码保存在一个文件中是不切实际的。这种解决方案适用于脚本,通常不超过几百行(通常比这短得多)。
一个完整的 Python 应用程序可能由数十万行代码组成,因此您将不得不将其分散到不同的模块中,这是更好的,但还不够好。事实证明,即使这样,使用代码仍然是不切实际的。因此,Python 为您提供了另一种结构,称为包,它允许您将模块组合在一起。包只是一个文件夹,必须包含一个特殊文件__init__.py
,它不需要包含任何代码,但其存在是为了告诉 Python 该文件夹不仅仅是一个文件夹,而实际上是一个包(请注意,从 Python 3.3 开始,__init__.py
模块不再严格需要)。
像往常一样,一个例子将使所有这些更加清晰。我在我的书项目中创建了一个示例结构,当我在控制台中输入时:
$ tree -v example
我得到了ch1/example
文件夹内容的树形表示,其中包含本章示例的代码。这是一个真正简单应用程序结构的样子:
example ├── core.py ├── run.py └── util ├── __init__.py ├── db.py ├── math.py └── network.py
您可以看到,在这个例子的根目录中,我们有两个模块,core.py
和run.py
,以及一个包:util
。在core.py
中,可能有我们应用程序的核心逻辑。另一方面,在run.py
模块中,我们可能会找到启动应用程序的逻辑。在util
包中,我希望找到各种实用工具,实际上,我们可以猜测那里的模块是根据它们所持有的工具类型命名的:db.py
将持有与数据库工作相关的工具,math.py
当然将持有数学工具(也许我们的应用程序涉及财务数据),network.py
可能将持有在网络上发送/接收数据的工具。
如前所述,__init__.py
文件只是告诉 Pythonutil
是一个包,而不仅仅是一个普通的文件夹。
如果这个软件只是组织在模块中,推断其结构将会更加困难。我在ch1/files_only
文件夹下放了一个仅模块的例子;自己看看:
$ tree -v files_only
这给我们展示了一个完全不同的画面:
files_only/ ├── core.py ├── db.py ├── math.py ├── network.py └── run.py
猜测每个模块的功能可能有点困难,对吧?现在,考虑这只是一个简单的例子,所以您可以猜想如果我们无法将代码组织成包和模块,要理解一个真实应用程序会有多困难。
我们如何使用模块和包?
当开发人员编写应用程序时,很可能需要在不同的部分应用相同的逻辑。例如,当编写一个解析器来解析用户可以在网页上填写的表单数据时,应用程序将需要验证某个字段是否包含数字。无论这种验证逻辑如何编写,很可能会在多个地方需要使用。
例如,在一个调查应用程序中,用户被问及许多问题,很可能其中几个问题需要数字答案。例如:
- 你多大了?
- 你有多少宠物?
- 你有多少孩子?
- 你结婚多少次了?
在每个期望得到数字答案的地方复制/粘贴(或者更恰当地说:重复)验证逻辑将是非常糟糕的做法。这将违反不要重复自己(DRY)原则,该原则规定您在应用程序中不应该重复相同的代码。我感到有必要强调这个原则的重要性:您在应用程序中不应该重复相同的代码(有意思的双关语)。
重复相同的逻辑可能非常糟糕的原因有几个,其中最重要的原因是:
- 逻辑中可能存在错误,因此,您将不得不在应用逻辑的每个地方进行更正。
- 您可能希望修改验证的方式,然后您将不得不在应用的每个地方进行更改。
- 您可能会忘记修复/修改某个逻辑,因为在搜索所有出现的时候错过了它。这将在您的应用程序中留下错误/不一致的行为。
- 您的代码会比需要的更长,没有好的理由。
Python 是一种很棒的语言,并为您提供了应用所有编码最佳实践所需的所有工具。对于这个特定的例子,我们需要能够重用一段代码。为了能够重用一段代码,我们需要有一个构造,可以为我们保存代码,以便我们可以在需要重复其中的逻辑时调用该构造。这个构造存在,它被称为函数。
我在这里不会深入讨论具体细节,所以请记住,函数是一块有组织的可重用代码,用于执行任务。函数可以根据它们所属的环境的不同形式和名称,但现在这并不重要。我们将在书的后面能够欣赏到它们时,再看到细节。函数是应用程序中模块化的构建块,几乎是不可或缺的。除非你在写一个非常简单的脚本,否则你会一直使用函数。我们将在第四章中探讨函数,函数,代码的构建块。
Python 自带一个非常庞大的库,就像我几页前已经说过的那样。现在,也许是定义库的好时机:库是提供丰富功能的函数和对象的集合,丰富了语言的能力。
例如,在 Python 的math
库中,我们可以找到大量的函数,其中之一就是factorial
函数,它当然可以计算一个数的阶乘。
在数学中,非负整数N的阶乘,表示为N!,被定义为小于或等于N的所有正整数的乘积。例如,计算 5 的阶乘如下:
5!= 5 * 4 * 3 * 2 * 1 = 120
0 的阶乘是 0!= 1,以遵守空乘积的约定。
因此,如果你想在你的代码中使用这个函数,你只需要导入它并用正确的输入值调用它。如果现在输入值和调用的概念不太清楚,不要担心,只需专注于导入部分。我们通过从中导入需要的内容来使用库,然后使用它。
在 Python 中,要计算数字 5 的阶乘,我们只需要以下代码:
>>> from math import factorial >>> factorial(5) 120
无论我们在 shell 中输入什么,只要它有可打印的表示,就会在控制台上打印出来(在这种情况下,是函数调用的结果:120)。
所以,让我们回到我们的例子,那个有core.py
、run.py
、util
等的例子。
在我们的例子中,包util
是我们的实用库。我们的自定义实用工具包,其中包含我们应用程序中需要的所有可重用工具(即函数)。其中一些将处理数据库(db.py
),一些将处理网络(network.py
),一些将执行数学计算(math.py
),这些都超出了 Python 标准math
库的范围,因此我们必须自己编写它们。
我们将在专门的章节详细讨论如何导入函数并在其中使用。现在让我们谈谈另一个非常重要的概念:Python 的执行模型。
Python 入门指南(一)(2)https://developer.aliyun.com/article/1507355