前言

著名软件工程师和企业家马克·安德森有句名言:“软件正在吞噬世界。”这句话最早在2011年被提出,随着时间的推移,其真实性越来越毋庸置疑。软件系统出现在了现代生活的各个角落,而且变得越来越复杂。程序员经常将Python视为自己最喜欢的语言(https://oreil.ly/RUNNh),从Web应用程序到机器学习,再到开发工具等,Python的影子随处可见。

不过,也并非所有发光的东西都是金子。随着软件系统变得越来越复杂,理解开发者的心理构想是如何映射到现实世界的也变得越来越困难。如果不对此加以检查,软件系统就会变得臃肿、脆弱,从而得到一个可怕的绰号:“遗留代码。”这些代码库经常会出现这样的警告:“不要碰这些文件,碰了就会出现问题,我们也不知道原因。”或者:“只有某某知道那个代码,可他两年前就去硅谷了。”软件开发是一个年轻的领域,但这些说法应该会让开发人员和商业人士感到有些害怕。

事实是,为了编写出持久的系统,开发人员需要慎重地做出选择。正如Titus Winters、Tom Manshreck和Hyrum Wright[1]所说的:“软件工程是随着时间的推移而集成的编程。”你的代码可能会存在很长一段时间——我曾经接触过一些代码是在我上小学那个年代编写的项目。你的代码会存在多长时间?它会比你现在的工作(或者当你完成那个项目的时候)持续更久吗?几年后,当有人用你的代码构建核心组件时,你希望获得怎样的评价?你是想让你的后继者感谢你的远见卓识,还是诅咒你给这个世界带来的复杂性?

Python是一种很棒的语言,但它偶尔会让未来的开发工作变得棘手。一些其他编程语言的支持者谴责Python不是产品级,或者谴责它只对原型开发有用。但事实是,许多开发人员只接触了Python的表面,而没有深入学习编写健壮的Python代码所需的所有工具和技巧。通过这本书,你将学会如何更好地使用Python。你将接触到许多使Python代码整洁且可维护的方法。你未来的维护者也将会喜爱使用你写出的代码,因为它是预先设计好的,可以让事情变得简单。所以,尽情通过阅读本书来展望未来,并构建令人敬畏的、持久的软件吧!

目标读者

本书适用于任何希望以可持续和可维护的方式编写代码的Python开发人员,但需要读者有一定的Python编程经验。你应该熟悉Python的控制流和类。如果你正在寻找更加入门级的资料,我建议你先阅读Mark Lutz的Learning Pythonhttps://oreil.ly/iIl2K)一书[2]

尽管我会讨论许多高级的Python主题,但本书的目标不是讲解如何使用Python的所有特性。相反,这些特性是关于健壮性以及你的选择是如何影响可维护性的更高层次的讨论的背景。有时我会讨论一些你平时较少使用的策略,这是因为我想先说明健壮性的首要原则,让大家理解为什么以及如何在代码中做决策比知道在最佳场景中使用什么工具更加重要。而在实践过程中,最佳场景其实很少出现。希望读者使用本书中的原则从自己的代码库中得出自己的结论。

这本书并不是参考书,你可以称它为讨论书。每一章的出发点都是便于组织中的开发人员一起讨论如何最好地应用这些原则。可以尝试成立一个读书俱乐部、讨论小组或午餐时间交流学习小组。我在每一章都提出了话题讨论以便开启对此的思考。当你遇到这些话题的时候,我鼓励你停下来检查一下当前的代码库。与你的同行进行交流,并使用这些话题作为跳板,讨论代码、流程和工作流的状态。如果你对Python语言的参考书籍感兴趣,我衷心推荐Luciano Ramalho的Fluent Python(第2版已于2021年年底由O'Reilly出版)一书。

一个系统能够以许多不同的方式保持健壮。它可以是安全加固的、可伸缩的、容错的,或者不容易引入新错误的。健壮性的每一个方面都可以单独写成一本书,本书的重点在于防止继承你代码的开发人员在系统中创建新的错误。我将展示如何与未来的开发人员沟通,如何通过架构模式让他们工作得更轻松,以及如何在代码库进入生产环境之前捕捉其缺陷。本书的关注点在于Python代码的健壮性,而不是整体系统的健壮性。

我将介绍许多不同软件领域的大量信息,包括软件工程、计算机科学、测试、函数式编程和面向对象编程(OOP)。你也许没有这些领域的背景知识,因此在一些章节中,我会按初学者的水平解释一些概念,通常这是为了解构我们对语言核心基础的思考方式。所以,在很大程度上,这是一本进阶书籍。

理想的读者包括:

•工作在大型代码库的开发人员,他们正在寻求更好的方式与同事交流。

•代码库的主要维护者,他们正在寻找帮助未来维护者减轻负担的方法。

•自学成才的开发人员,他们可以很好地编写Python程序,但需要更好地理解所做和要做的事情。

•软件工程专业的毕业生,他们需要实用的开发建议。

•高级开发人员,他们正在寻找将设计原理与健壮性的首要原则联系起来的方法。

本书的重点是编写健壮的软件。如果你的很多代码都是原型或用过即弃的,那么书中的建议将会制造更多的工作量。同样,如果你的项目很小,比如只有不到100行的Python代码,那么毫无疑问,写出可维护的代码增加了复杂性。然而,我将引导你尽量减少这种复杂性。如果你的代码寿命超过几周或者代码量会增长到很大的体量,那么则需要考虑代码的可持续性了。

关于本书

本书涵盖了非常广泛的知识,我把它主要分为了四个部分:

第一部分,为代码添加类型注解

我们将从Python中的类型开始。类型是语言的基础,但开发人员往往没有对其进行详细检查。开发人员选择的类型很重要,因为它们传达了非常具体的意图。我们将介绍类型注解以及要与开发人员沟通的具体注解。我们还将介绍类型检查器以及它们是如何帮助开发人员在早期捕获bug的。

第二部分,定义你自己的类型

在介绍了如何考虑Python的类型之后,我们将重点关注如何创建自己的类型。我们将深入讨论枚举、数据类和类,并探讨在设计类型时特定的选择会如何增加或减少代码的健壮性。

第三部分,可扩展的Python

在学习了如何更好地表达你的意图之后,我们将重点关注如何使开发人员能够轻松地更改你的代码,并在你的基础上充满信心地构建代码。我们将讨论可扩展性、依赖关系和架构模式方面的问题,这些方面使你可以在最小的影响下修改系统。

第四部分,构建安全网

最后,我们将探讨如何构建一个安全网,这样你就可以在未来的合作者失误时帮助他们。他们的信心会因此而增强,因为他们会知道自己有一个强大的、健壮的系统,可以无所畏惧地用于他们的用例。最后,我们将介绍各种静态分析和测试工具,它们将帮助你捕获恶意的行为。

每一章基本上都是独立的,你既可以按照顺序从头到尾阅读,也可以根据自己的需求阅读相应的章节。各部分中的章节相互关联,但各个部分之间的关联较少。

所有代码示例都是用Python 3.9.0运行的,当你需要使用特定的Python版本(例如使用数据类的Python 3.7)或更高版本来运行示例时,我会对此做出提示。

本书中的大部分工作都是在命令行上完成的。我在Ubuntu操作系统上运行了所有这些命令,但大多数工具在Mac或Windows系统上也可以正常工作。在一些情况下,我将展示某些工具如何与集成开发环境(IDE)交互,如Visual Studio Code(VS Code)。大多数IDE在底层使用命令行选项,你在命令行中学到的大部分内容将直接对应IDE选项。

本书将介绍许多不同的可以提高代码健壮性的技术。然而,在软件开发中没有“银弹”。权衡是可靠的工程的核心,在我所介绍的方法中也不例外。在讨论这些话题时,我会坦率地说明利弊。你会比我更了解你的系统,因此你是最适合选择自己的工作工具的人,而我只是在帮你充实你的工具箱。

排版约定

本书中使用以下排版约定:

斜体(Italic

表示新的术语、URL、电子邮件地址、文件名和文件扩展名。

等宽字体(Constant width)

用于程序清单,以及段落中的程序元素,例如变量名、函数名、数据库、数据类型、环境变量、语句以及关键字。

等宽粗体(Constant width bold

表示应由用户直接输入的命令或其他文本。

等宽斜体(Constant width italic

表示应由用户提供的值或由上下文确定的值替换的文本。

该图示表示提示或建议。

该图示表示一般性说明。

该图示表示警告或注意。

示例代码

可以从https://github.com/pviafore/RobustPython下载补充材料(示例代码、练习、勘误等)。

这里的代码是为了帮助你更好地理解本书的内容。通常,可以在程序或文档中使用本书中的代码,而不需要联系O'Reilly获得许可,除非需要大段地复制代码。例如,使用本书中所提供的几个代码片段来编写一个程序不需要得到我们的许可,但销售或发布O'Reilly的示例代码则需要获得许可。引用本书的示例代码来回答问题也不需要许可,将本书中的很大一部分示例代码放到自己的产品文档中则需要获得许可。

非常欢迎读者使用本书中的代码,希望(但不强制)注明出处。注明出处时包含书名、作者、出版社和ISBN,例如:

Robust Python,作者Patrick Viafore,由O'Reilly出版,书号978-1-098-10066-7。

如果读者觉得对示例代码的使用超出了上面所给出的许可范围,欢迎通过permissions@oreilly.com联系我们。

O'Reilly在线学习平台(O'Reilly Online Learning)

40多年来,O'Reilly Media致力于提供技术和商业培训、知识和卓越见解,来帮助众多公司取得成功。

我们拥有独一无二的专家和革新者组成的庞大网络,他们通过图书、文章、会议和我们的在线学习平台分享他们的知识和经验。O'Reilly的在线学习平台允许你按需访问现场培训课程、深入的学习路径、交互式编程环境,以及O'Reilly和200多家其他出版商提供的大量文本和视频资源。有关的更多信息,请访问http://oreilly.com

如何联系我们

对于本书,如果有任何意见或疑问,请按照以下地址联系本书出版商。

美国:

O'Reilly Media,Inc.

1005 Gravenstein Highway North

Sebastopol,CA 95472

中国:

北京市西城区西直门南大街2号成铭大厦C座807室(100035)

奥莱利技术咨询(北京)有限公司

要询问技术问题或对本书提出建议,请发送电子邮件至errata@oreilly.com.cn

本书配套网站https://oreil.ly/robust-Python上列出了勘误表、示例以及其他信息。

关于书籍、课程、会议和新闻的更多信息,请访问我们的网站http://oreilly.com

我们在Facebook上的地址:http://facebook.com/oreilly

我们在Twitter上的地址:http://twitter.com/oreillymedia

我们在YouTube上的地址:http://www.youtube.com/oreillymedia

致谢

感谢我的妻子Kendall。她是我的支持者和参谋,我很感激她为了确保我有时间和空间写这本书所做的一切。

没有一本书是独立完成的,这本书也不例外。我站在巨人的肩膀上,感谢所有软件行业的前辈们。

感谢每一个参与审阅这本书的人,他们确保我的信息是及时更新的,表达是清晰的。感谢Bruce G.、David K.、David P.和Don P.早期提供的反馈,帮助我决定这本书的方向。感谢技术审校者Charles Givre、Drew Winstel、Jennifer Wilcox、Jordan Goldmeier、Nathan Stocks和Jess Males给予宝贵的反馈,尤其是帮助我把脑中的东西展现出来。最后,感谢那些阅读了早期草稿版本并将他们的想法发邮件给我的人,特别是Daniel C.和Francesco。

感谢所有帮助我把终稿变得有生产价值的朋友们。感谢编辑Justin Billing深入研究并帮助完善我的想法和陈述。感谢Shannon Turlington的校对工作使本书变得更加精练。感谢Ellen Troutman-Zaig写了一个很棒的索引,让我非常惊喜。

最后,如果没有O'Reilly出色的团队,本书也无法顺利出版。感谢Amanda Quinn帮助我通过了选题,并帮助我确定了本书的重点。感谢Kristen Brown让我在制作阶段非常轻松。感谢Kate Dullea把我的MS草图整理成更加整洁、清晰的插图。还有,非常感谢我的编辑Sarah Grey。通过每周例会,她非常出色地帮助我编写了一本适合大多数读者阅读的书,还和我深入研究了技术细节。


[1]Titus Winters, Tom Manshreck, and Hyrum Wright. Software Engineering at Google:Lessons Learnedfrom Programming over Time.Sebastopol, CA:O'Reilly Media, Inc., 2020.

[2]该书中文版《Python学习手册(原书第5版)》由机械工业出版社出版,书号978-7-111-60366-5。