/best-practice-python

常常有人问,在大型项目上,Python是个烂语言吗?这本书回答了使用Python构建大型应用所需要的软件工程相关的知识,即如何使用lint,type hint, unit test, CI,git以及如何构建文档。

Primary LanguagePython

多年以来,Python一直占据TIOBE最热门编程语言的榜单前三,在2023年度的最新评选中,又高居榜首。正所谓名满天下,谤亦随之,一直以来,争议一直伴随着Python。其一是性能,其二是动态类型导致Python项目无法大型化。在知乎上,话题"大型项目上,Python是个烂语言吗",最高的一个回答,点赞数达到了4700。说明这个话题,无论观点是否正确,还是很能引起共鸣的。

我从2019年开始大富翁量化框架开发起,就决心把它打造成一款开源产品。不仅仅是要把代码开源,而且是要达到开源社区的优质标准。我开始注意到,一些优秀的开源项目,代码一旦克隆下来,可以直接运行(单元测试),而另外一些项目,还会存在依赖缺少的问题 -- 作者并不知道他在本地可以运行的代码,在其它人那里是不工作的;优秀的开源项目即使支持多个操作系统、多个Python版本,开发者仍然是兼职的并且维护得很及时,那他们是怎么做到的,时间是怎么挤出来的?有些开源的项目,他们的文档做得非常好,特别是关于API的说明,有些文档中的示例都进行了测试,还有指向其它API的链接,这都是怎么做到的?

所有的这些,好象最终都指向了软件工程的最佳实践。优秀的开源项目,往往只有少量的开发者,只能利用业余时间,如果没有一套良好的开发流程规范,是不可能做到的。从此,我不仅开始了量化框架的探索,还开始了Python软件工程最佳实践的探索。因为我深知,如果大富翁量化框架如果不能在软件工程上有一个良好的实践,以它的工程量之大,是很难完成并保证质量的。

最终,在考察了众多的工具、技术和社区实践,以及查阅PEP文档之后,我找到了一套Python软件工程最佳实践,并通过Python Project Wizard这个工具,基本上把流程和中间要使用的工具固定下来。

本书不是一本介绍如何使用Python来完成某个具体功能的书,相反,它是用来帮助那些已经能开发一些Python功能,但在开发规范上无法入门,无法构建大型项目或者在大型项目开发中实现协作的读者的。它适合有一定Python基础,想要进一步提升自己的Python开发技能,从而能够参与或者领导大型项目开发的读者。如果你的团队正在打算开发一个大型项目,或者可能持续好几个版本的项目,建议一定要了解本书中介绍的工具、技术和规范。

本书旨在强调这样一个原则:软件开发流程不应该是一些抽象的理念,而应该是通过一系列工具,得以强制执行的软件生产流水线。

本书是按照Python项目开发的生命期顺序来展开的。

我们首先介绍了Python开发环境的搭建过程,我们从操作系统的选择开始,讲到集成开发环境的选择。在这一章里提到了Pycharm和VS Code,并着重介绍了VS Code这个工具。我们还介绍了许多非常好用的VS Code扩展。由于Python社区的开源传统,许多知名的Python库都优先考虑与Linux的兼容性,因此,更多的开发者都选择了Linux作为开发环境。考虑到部分读者可能没有独立的Linux机器可供使用,我们还介绍了如何在Windows机器上通过wsl技术来运行一个Linux操作系统。

在第三章,我们介绍了如何构建Python的虚拟环境,并梳理了Python虚拟环境管理中出现的超过10种以上的各式各样的技术,指出使用Anaconda或者VirtualEnv是未来一段时间的主流技术,接着我们主要介绍了如何使用Anaconda,并且指出对一般的软件开发工程师(相对于数据科学工程师)来说,我们应该使用Miniconda -- 一个轻量级的Anaconda版本。

在前三章,读者可能不会感觉到太多的阅读困难,毕竟有一些技术和工具,可能您已经正在使用了。但从第四章开始,我们一下子接触很多平常可能使用得较少的工具和技术,特别是对刚入门Python不久,还没有机会做过大型项目的读者来说,尤其如此。在这一章,我们正式引入了Python Project Wizard,从而不得不让许多新颖的技术和工具一下子涌入进来。不过,我们在这一章里,主要了解一个标准的项目应该如何布局(即文件及其结构)即可,我们在后面会逐一剖析这些技术。

第五章我们会基于Python Poetry这个工具,来介绍如何进行依赖管理。这里您会接触到一些新概念,比如基于语义的版本管理(Semantic Versioning),比如依赖地狱等。我们还会讲述一个因为版本管理上的失误,一些著名的软件是如何引起巨大的灾难的故事。不过请放心,这一章结束后,我们最终将带您永别依赖地狱。

在第六章,我们会介绍如何更高效地写Python代码。效率的提升可能来自两方面。一方面,我们可以借助AI辅助工具,相信一部分人已经利用上了了Github Copilot或者OpenAI的chatGPT,一时接触不到这两种产品的用户也不用着急,我们还提供了其它好用的替代品。另一方面,我们通过改进代码的可读性,提升代码的可维护性,从而提升代码的效率。在这一章我们会看到lint工具的使用,代码格式化工具的使用,以及如何给代码加上Type Hint的。可能出人意料的是,一些文章里大吹特吹的PEP8在这里我们几乎不会提及。因为实际上你没有必要了解PEP8的大多数规范,因为ppw生成的项目中使用了black这个代码格式化工具,black就是符合PEP8规范的。

第七章我们介绍了单元测试。这是我们为数不多的大段引用代码的一章。我们的重点在于教会大家如何使用mock来进行单元测试。使用mock是几乎所有语言中,进行单元测试时的最重要和最难懂的技巧。在这里,我们也会接触如何使用tox来自动化多个Python版本下的测试,以及如何评估我们测试的完备性。

任何严肃的开发都离不开版本管理,对大型项目尤其如此。关于版本控制,通常是一本书的内容,不过我们在这里将其精华进行了浓缩,对延展部分,我们也准备了参考资料。

第九章我们会介绍如何进行持续集成。我们会介绍如何使用Github Actions平台,以及Github Actions语法。对个人开发者或者任何有成本控制需求的团队,都应该使用Github Actions来进行持续集成。因为它提供了免费的MacOs, Windows和众多Linux机器资源供我们使用。如果我们要自行搭建有这么多机器的测试平台,费用既昂贵,利用率也低。

第十章我们介绍如何写作技术文档。我们将介绍reStructureText和Markdown两种文档格式,以及相应的构建工具。掌握这些技术,不仅可以帮助我们写出更好的技术文档,也可以用来构建自己的博客,或者编写书籍。实际上,这本书就是利用我们在这一章所介绍的技术来创作和构建的。

开发的终点是发布。在第十一章,我们将介绍如何向全世界发布你的作品。我们将介绍各种级别的发布,从发布一个Python库(package),到发布一个桌面应用,再到通过容器技术来发布一个镜像。在这里,你还将学到如何将Python程序打包成原生应用,从而使得我们的应用可以在没有安装Python的机器上,以一般用户熟悉的启动方式启动运行。在这一章,我们还会得到一个意外的收获,那就是如何加密Python程序,并且提高运行性能。

本书提供的示例代码可以在Github1上找到。

Footnotes

  1. 本书源码在https://github.com/zillionare/best-practice-python项目中的code目录下。