提高Python代码可读性的5个必备技巧2025年1月4日 | 阅读 11 分钟 然而,这与软件工程有所不同,主要是因为作为数据科学家,我们可以相当独立地处理代码。是的,你也会在团队中工作,但很少会参与到一个项目中,或者至少根据我的经验,你很少会与同事编辑同一个文件,并且通常一个人负责项目的一部分。这主要意味着它不会是一个多人负责同一代码段的团队责任,而是会指定一个人承担这项职责。这往往会导致许多项目的代码看起来相当混乱,并且以各种不同的方式进行格式化;花在确保代码易于阅读,特别是易于您的项目团队中的其他成员维护上的时间要少得多。自我的职业生涯的第一天起,我大部分的经验都集中在“绿色田野”项目的咨询职位上。这些项目通常包括自动创建新代码。 1. 推荐使用自动格式化工具来格式化代码提高代码可读性最简单的方法是使用自动代码格式化功能,这些功能可以确保您的代码符合通用的编码系统。在 Python 中有几种格式化代码的方法。其中一些最流行的包括:在 Python 环境中推荐使用的工具有 Black、isort、autopep8 和 YAPF。 建议专门使用 Black 进行代码格式化,并使用 isort 来组织库的导入。在项目中使用简单一致的代码风格或格式,可以使其他程序员更容易阅读代码。 简单来说,理解格式混乱的代码就像阅读一篇有语法错误的、令人不快的文章一样困难。你可以读出单词,但它们在句法中的排列方式,有时你可以推断出意思,但会含糊不清,在某些情况下,还会相当令人困惑。 符合 PEP8 标准的格式化风格的一致性,有助于开发人员阅读代码。他们已经知道代码中的一切应该在什么位置,可以专注于代码的实际“核心”,而不是布局。 通过版本控制中的标准化和自动化,代码格式化也变得更加容易。显然,可以考虑以下情况:您生成了一个不符合 PEP8 标准的新文件。然后,您的同事在版本控制中打开该文件并修改了一行代码。当他们保存文件时,他们的 IDE 会重新格式化原始文件,使其符合 PEP8 标准(例如,他们之前显示的最大行长度为 79 个字符,函数之间有多个空行,函数参数中有多余的空格等)。然后,他们会将文件提交回存储库。现在,随着从绝对主义的转变,状态会变得更糟,出现了问题。他们包含了一个链接,“diff”,显示了旧代码和更新代码之间存在巨大差异,即使底层代码逻辑的更改非常小。统一的、基于脚本的代码格式化减少了版本系统中与修改代码的功能无关的巨大 diff 的可能性。 如何使用代码格式化工具?有许多自动代码格式化工具可以从命令行运行您的代码。否则,大多数 IDE(如 VS Code)的当前版本都提供选项或扩展,可以在每次保存文件时自动格式化代码。 例如,在命令行中,您可以使用以下命令将 Black 代码风格应用到您的代码中,并使用 isort 来组织您的导入:例如,在命令行中,使用以下命令将 Black 代码风格应用到代码中,并使用 isort 来组织您的导入 这是我 VS Code settings.json 文件的一部分的表示,我检测到它会在 VS Code 中打开 Python 文件时自动应用 Black 格式化,并在保存时。它还对我的导入进行分类,这与 isort 类似,因此它可以排列导入语句,当导入了许多库或函数时,可以使人类易于阅读。 注意:虽然要求遵循 PEP8 编码约定,但并没有普遍接受的 Python 代码风格规则。项目中所有团队成员必须遵守相同的代码风格规则。因此,最好明确说明您遵循的是哪种风格指南。2. 使用代码检查工具(Linters)来捕获错误并遵循最佳实践静态分析器,也称为 Linters,允许您在 Python 代码中识别语法和风格问题。 Linters 帮助您根据 PEP8 维护代码的美观性,在执行代码之前检查代码中的错误,并告知您错误的做法。 例如 识别未使用的变量或在赋值前使用的变量,识别未使用的导入库,确保所有函数/类都有文档字符串,并反对所谓的裸露异常。 需要理解的是,有时 linter 指出的违规行为根本不是问题。例如,pylint 建议每个 Python 模块都应包含一个描述其功能的文档字符串。您可能同意对于您的项目来说这不是必需的。可以通过直接配置文件或代码中的注释来管理 linter 的行为,可以设置为忽略某些错误。 同样,Python 有大量的 linting 工具可用。最常见的两个是:flake8 和 pylint。我主要使用 flake8 进行 pre-commit hooks(请参阅下面的提示)。在开发过程中,我还使用 Pylint 来帮助查找问题并通知潜在的改进,但是,与 flake8 不同的是,它对看似无害的问题过于唠叨,这使得它作为防止新代码提交到仓库的最后一道防线几乎无效。 Pylint 还以百分比的形式为您的代码评分,10 分满分,这相当不错。尽管如此,即使它可能伤及您的自尊心,但它也可能给您完全正常工作的代码打 3 分(满分 10 分)。 如何使用 Linters 检查代码?目前,您可以从 settings.json 文件中启用 VS Code 中的 linting。例如,使用 pylint 注意:使用 nbQA 库将代码检查工具扩展到您的 Jupyter Notebook。如果您使用 Jupyter Notebook,代码检查工具的使用与 .py 文件一样重要,甚至更重要。由于 Jupyter Notebook 的特性,中间工作中进行的所有工作很可能仍在进行中,并且在修复问题时可能需要以不同的顺序运行单元格。因此,很容易无意中出现未初始化的变量或引用尚未定义的变量。在将 notebook 写入 git 存储库之前的准备阶段,很难单独识别这些问题。nbQA 在您的 notebook 上执行 Python linting 工具,以检测您的存储库中是否检查了损坏的 notebook。3. 静态类型提示在我的代码中进行类型提示对我来说是改变游戏规则的。我告诉您,当您开始遵守类型提示原则时,您的代码可读性就会得到最好的体现。如果您应该从本文中记住任何内容,那就是立即开始练习类型提示。 类型提示Python 属于动态类型语言。这意味着您不会在代码中直接声明变量的数据类型。由于在代码执行期间将特定类型的数据结构分配给特定变量,因此它会获得其数据类型。 动态类型语言中缺少类型检查也有助于减少语法开销——所有上述语言对于新手程序员来说都相对容易上手,并且不会对编码者施加太多不必要的限制;但是,这很快就会变成一个缺点,因为它有利于不良习惯的形成,并导致代码往往非常混乱且难以阅读,特别是当项目规模扩大时。 Python 中的类型提示(从 3.6 版本开始)是放在注释中的注解,告知您代码的最终使用者您期望的变量或函数的 数据类型/结构。例如,str、list、dict、int 等。 Python 解释器不关心类型提示,问题在于 Python 的类型提示非常有限,而 Java 的类型系统非常丰富。类型提示不会减慢您的代码速度,如果您根本没有提供类型提示,或者提供了错误的类型提示,您的代码仍然会像以前一样运行。类型提示的概念完全是为了开发人员的角度。 例如 以下是一个典型的函数,可以在其中应用类型提示来增强开发工作流程 实际上,上面的函数应该接受一个数字列表作为参数,并返回列表中的最大值。很简单,对吧? 现在,您作为一名开发人员刚接触这个项目,遇到了这段代码。那么,您何时以及如何使用此函数? 编写函数的作者当然非常清楚它的作用——这是一个非常简单的 Python 脚本。尽管如此,对于新开发人员来说,模糊性是显而易见的,他们可能会错误地使用该函数或获得意想不到的结果。 这个例子中最大的问题是:应该将什么类型的数据结构传递给名为 items 的函数参数? Python 中的 max 关键字可以与多种不同的数据结构一起使用,包括数组、链表、字符串、字符串数组、集合和元组。如果传递了这些数据结构中的任何一个,上面的函数都不会报错。但是,仅包含整数的列表才会产生原始开发人员期望的程序行为;它也可以是浮点数。 虽然无法阻止未来的开发人员意外地将字符串或字符串列表传递给此函数,但类型提示可以帮助开发人员并指示此函数的使用方式。 用于类型提示的工具对于可疑的类型错误,如果您使用的是 vs code,可以使用 mypy 和 pylance。 如果您设置了类型提示,这些工具将扫描您的代码以查找该变量/函数的用法,并确保使用的是正确的数据结构。 4. 使用 Pre-Commit Hooks 自动化一切程序员喜欢自动化事物,这就是为什么有一个全新的测试领域叫做自动化测试。代码的格式化和检查也不应例外。可以自动化的方面包括代码样式和与样式相关的检查,使用 pre-commit hooks。pre-commit 配置允许您选择在将更改提交到 git 存储库之前应该针对代码运行哪些测试。这些检查在代码的提交操作时执行。所有检查都是严格条件的,如果失败,代码将不会继续,直到得到纠正。 这可以防止不希望出现在任何项目历史中的不良代码被添加到存储库,并保证所有代码都符合既定的代码风格标准。 启动 Pre-Commit Hook1. 安装 pre-commit 2. 将配置文件添加到项目目录。 3. 安装 hooks 遵循这些说明后,下次尝试将文件提交到存储库时,pre-commit hooks 将检查您即将提交的代码是否符合 black 格式化器。在上述情况下,pre-commit 还会清除文件末尾的空白。 您可以在我关于它的文章中找到关于 pre-commit hooks 的更详细的教程,以及我的完整模板。pre-commit-config。请参考 .yaml 文件作为我的数据科学配置 .yaml 文件。 5. 编写文档这就是为什么我们都希望我们编写的代码在我们不参与项目时仍然保持活跃。因此,无论您的软件有多好;如果文档不好,人们就不会购买或使用它。文档通常是在开发过程中被半途而废的事情,很容易被忽视。它通常是项目最后才得到关注的方面。 为仍在开发中的功能编写良好且篇幅巨大的文档是没有意义的——提供错误信息不如什么都不写,但有几个简单的规则可以帮助您不至于完全迷失方向,并且不会过度劳累。另一个重视更好文档的原因是,其他人利用您的代码的可能性会很高,这也会在将来减轻您的工作。 在 Python 中,文档通常有三种形式:代码内的注释(通常称为行内注释),函数/方法开头的注释(文档字符串),以及外部文档文件中的注释(例如 README 文件)。 至于代码的作用,嗯,这应该从前面的部分可以很明显地看出来。另一方面,这个“魔法”数字、不寻常的方法或开发人员产生的解决方法是如何产生的,则不清楚。这就是为什么行内注释很合乎逻辑。当代码的意图不太清楚时,请使用行内注释。例如,当您使用颜色代码的 HEX 代码时——在这种情况下,您永远不会仅仅通过查看十六进制代码来记住颜色。为您的代码函数添加简单的单行文档字符串,即使您认为该函数是独一无二的,也能大大提高可读性并减少未来开发人员的歧义。重要的是要注意,文档字符串和行内/块注释不能互换。 另一方面,行内/块注释和文档字符串可以通过 __doc__ 魔术属性或内置的 help() 函数在代码运行时访问。这表明文档字符串可以被 IDE 读取并在键入新代码时作为提示显示。可以注意到,来自不同语言的程序员没有正确利用 Python 的文档字符串功能。 结论编写高效的代码是一种最佳实践,不仅可以提高 Python 代码的可读性,还可以给人留下好印象。使用注释和工具来提高 Python 代码的可读性。 |
我们请求您订阅我们的新闻通讯以获取最新更新。