page contents

用 Python 中的 Linting 提高代码质量

Python 是一种不断发展的语言。随着它的演化和扩展,可用工具和开发策略的数量也在增加。近来流行的一个过程是linting —— 检查代码的潜在问题。通过linting,我们代码中的错误会被标记出来,这样我们就可以纠正可能导致出现问题的编程方法。

attachments-2025-01-EXAcTQu5677dd7011e811.pngPython 是一种不断发展的语言。随着它的演化和扩展,可用工具和开发策略的数量也在增加。近来流行的一个过程是linting —— 检查代码的潜在问题。通过linting,我们代码中的错误会被标记出来,这样我们就可以纠正可能导致出现问题的编程方法。

Linting(提示)是在编写源代码时和编译前进行的。换句话说,Linting是一种构建前的检查,也叫 "静态代码分析"。定期检查我们的代码,以确保整个代码和代码库的一致性。这最大限度地减少了小错误在代码运行后变成复杂问题的机会。

许多开发人员不使用Linting,因为他们没有看到它的附加价值,因为Linting不会防止错误。但这种观点低估了Linting在提高代码质量方面的价值。

在这篇实践文章中,我们将探讨在Python中使用Pylint——最流行的提示工具之一——进行快速的提示检查是多么快速和简单。我们还将看到,对代码进行提示是如何帮助我们遵守PEP8代码风格指南的。

前提条件

在开始之前,确保满足以下条件:

  • 在你的机器上安装了Python和pip

  • 对命令行界面(CLI)有基本的了解

  • 对Python概念的理解,如函数和类。

另外,应该注意,虽然这里显示的命令与Linux和基于macOS的系统兼容,但在Windows下工作时,你应该小心。

Linting Python 代码

在我们深入研究如何在Python中使用linter之前,让我们通过创建一个目录和虚拟环境来进行设置。

建立环境

首先,为这个项目创建一个目录。在本教程中,我们把它叫做 pylint-demo



  1. $ mkdir pylint-demo


  2. $ cd pylint-demo

接下来,创建一个虚拟环境。这将隔离我们的项目依赖性,并防止与其他项目发生冲突。



  1. $ pip install pipenv


  2. $ pipenv shell

命令行应该是这样的。(pylint-demo)$。这表明虚拟环境已经激活。

在虚拟环境激活的情况下,使用下面的命令安装linter。



  1. $ pipenv install pylint

现在我们可以用pylint命令运行linter。为了确保Pylint已经成功安装,运行以下命令。



  1. $ pylint help

开始使用 Linting

让我们写一个基本的Python程序,并在其上使用Pylint,看看它是如何工作的。创建一个 main.py文件并复制以下代码。



  1. def is_number_even(num):

  2. return"Even"if num %2==0else"Odd"


  3. num =5

  4. print(f"The number {num} is {is_number_even(num)}")

在上面的代码中,我们已经添加了一个函数来检查数字是偶数还是奇数。为了使用Pylint来检查这段代码中的错误,我们使用以下命令:



  1. $ pylint <<file_name>>

  2. $ pylint main.py

Pylint的输出情况如下:



  1. *************Module main

  2. main.py:12:0: C0304:Final newline missing (missing-final-newline)

  3. main.py:1:0: C0114:Missingmodule docstring (missing-module-docstring)

  4. main.py:8:0: C0116:Missingfunctionor method docstring (missing-function-docstring)

  5. main.py:8:19: W0621:Redefining name 'num'from outer scope (line 11)(redefined-outer-name)

  6. main.py:11:0: C0103:Constant name "num" doesn't conform to UPPER_CASE naming style (invalid-name)


  7. ------------------------------------------------------------------

  8. Your code has been rated at 0.00/10 (previous run: 0.00/10, +0.00)

我们可以在代码中看到几个不言而喻的问题,每个问题都用一个字符标识,如 C0304。Pylint将字母代码应用于所有错误,以区分问题的严重程度和性质。有五个不同类别的错误。

  • C: 惯例(针对任何违反代码惯例的行为)

  • R:重构(针对任何与代码气味和重构有关的问题)

  • W:警告(针对任何不属于错误的编程级问题)

  • E: 错误 (对于任何编程级别的问题,是一个错误)

  • F: Fatal (对于任何停止Pylint执行的严重问题)

Pylint还根据存在的错误数量给我们的代码打分,满分为10分。

在我们的例子中,除了一个错误代码外,所有的错误代码都是约定俗成的错误——单个错误是一个警告。为了解决这些问题,让我们在我们的代码中做一些修改,然后再次运行Pylint,看看我们的代码得到什么分数。



  1. """ File contains various function to under Pylint """


  2. def is_number_even(num):

  3. """Function to check if number is even or odd"""

  4. return"Even"if num %2==0else"Odd"


  5. NUM =5

  6. print(f"The number {NUM} is {is_number_even(NUM)}")

通过这段代码,我们添加了一个模块和函数docstring,在结尾处添加了一个新行,并重新命名了上述代码中的变量。当我们重新运行Pylint时,我们得到了10/10的分数,没有任何问题。

在单个文件上运行Pylint

现在我们对Pylint的工作方式更加熟悉了,让我们看看另一个例子,输入以下代码:



  1. """ File contains various function to under Pylint """


  2. class animal:

  3. def __init__(self, name):

  4. self.name = name


  5. obj1 = animal("Horse",21)

  6. print(obj1.name)

在这个片段中,我们有一个简单的类,名为 animal,该类的一个对象名为 obj1。现在让我们在这段代码上使用Pylint:



  1. *************Module main

  2. main.py:4:0: W0311:Bad indentation.Found2 spaces, expected 4(bad-indentation)

  3. main.py:5:0: W0311:Bad indentation.Found4 spaces, expected 8(bad-indentation)

  4. main.py:3:0: C0115:Missingclass docstring (missing-class-docstring)

  5. main.py:3:0: C0103:Class name "animal" doesn't conform to PascalCase naming style (invalid-name)

  6. main.py:3:0: R0903: Too few public methods (0/2) (too-few-public-methods)

  7. main.py:7:7: E1121: Too many positional arguments for constructor call (too-many-function-args)

请注意,虽然这次我们没有代码质量问题,但它们已经被更多实质性的错误所取代。有了这些问题的标记,让我们试着用下面的代码来修复它们:



  1. """ File contains various function to under Pylint """


  2. classAnimal:

  3. "Animal Class"

  4. def __init__(self, name):

  5. self.name = name


  6. obj1 =Animal("John")

  7. print(obj1.name)

然后,重新运行Pylint。在将类的名称从 animal改为 Animal,为类添加一个文档字符串,删除函数调用中不需要的参数,并添加适当的缩进,我们几乎消除了代码中的错误。不过还剩下一个:



  1. *************Module main

  2. main.py:3:0: R0903:Too few public methods (0/2)(too-few-public-methods)

让我们看看如何解决这个剩余的错误。Pylint说我们没有两个或多个公共方法,但我们的代码很有可能没有两个或多个公共方法。那么,我们该如何解决这个问题呢?

在这样的情况下,我们可以使用Python注释来抑制这些问题。抑制它们的语法如下。



  1. # pylint: disable=<<issue_name>>

下面是完整代码:



  1. """ File contains various function to under Pylint """


  2. # pylint: disable=too-few-public-methods

  3. classAnimal:

  4. "Animal Class"

  5. def __init__(self, name):

  6. self.name = name


  7. obj1 =Animal("John")

  8. print(obj1.name)

当我们现在检查Pylint的输出时,我们会看到这个问题已经消失了。

在一个目录上运行Pylint

我们已经看到了如何在单个文件上运行Pylint,但是当我们在一个项目上工作时,我们不会有单个文件可以检查。

要在整个目录上使用Pylint,请运行以下命令。



  1. $ pylint <<name_of_directory>>

为了了解对一个目录的提示是如何工作的,让我们再创建两个文件并添加一些代码。



  1. $ mkdir src; cd src

  2. $ touch helpers.py config.py __init__.py

main.py文件移到 src目录,并将以下代码粘贴到相应的文件中。



  1. <<main.py>>

  2. """ File contains various function to under Pylint """


  3. from helpers import connect_db

  4. from config import DB_USER, DB_PASS


  5. is_connected = connect_db(DB_USER, DB_PASS)


  6. if is_connected:

  7. print("Connected to DB")

  8. else:

  9. print("Failed to connect to DB")


  10. <<helpers.py>>

  11. def connect_db(user, password):

  12. """Dummy function to connect to DB"""

  13. if user is None or password is None:

  14. return False

  15. return True


  16. <<config.py>>

  17. DB_USER = "root"

  18. DB_PASS = "toor"

我们在 src目录下有三个文件:main.pyhelpers.pyconfig.py。在 main.py中,我们有一个假函数来打印我们是否连接到了DB。helpers.py包含一个假的帮助函数来连接到DB, config.py文件包含DB的用户名和密码。

现在,让我们在根目录下使用以下命令在整个目录上运行Pylint。



  1. $ pylint src

命令的输出将如下:



  1. *************Module src.config

  2. src/config.py:2:0: C0304:Final newline missing (missing-final-newline)

  3. src/config.py:1:0: C0114:Missingmodule docstring (missing-module-docstring)

  4. *************Module src.main

  5. src/main.py:11:0: C0304:Final newline missing (missing-final-newline)

  6. src/main.py:3:0: E0401:Unable to import'helpers'(import-error)

  7. src/main.py:4:0: E0401:Unable to import'config'(import-error)

  8. *************Module src.helpers

  9. src/helpers.py:6:0: C0304:Final newline missing (missing-final-newline)

  10. src/helpers.py:1:0: C0114:Missingmodule docstring (missing-module-docstring)

我们可以看到,Pylint向我们显示了不同文件的输出,用 ***和模块名称分开。为了解决这些问题,我们需要做以下修改。

  • 在每个文件的末尾添加一个新行。

  • 为每个文件和函数添加一个文档串。

  • 将 import语句从 helpersimportconnect_db修改为 .helpersimportconnect_db

一旦我们解决了这些问题,我们会看到另一个问题——我们需要将 is_connected变量大写。我们可以改变变量名称,或者抑制警告来处理这个错误。

抑制警告

在对Python代码进行检查时,你很有可能需要定制或抑制多个警告。每次都添加注释是没有意义的。你可以创建一个 .rc文件来定制Pylint的行为,并直接从 .rc文件中抑制整个项目的警告,而不是一个一个地处理警告抑制实例。

你可以用下面的命令创建一个:



  1. $ pylint --generate-rcfile > pylint.rc

用Linting更好、更安全地编写代码

在Python中,在代码编写过程中对源代码进行检查,并在我们运行代码之前,沿途标记出错误。你也可以将Pylint嵌入到编辑器中,实时查看提示信息。

虽然提示并不能自动修复错误,但持续使用它有助于确保我们的代码质量保持高水准。因此,虽然有些开发者认为linting是浪费时间,但它在小问题滚雪球般发展成大问题之前就能极其有效地捕捉到。

在这篇文章中,我们已经探讨了如何通过linting和实施Pylint的建议来改善我们的示例代码。此外,这个过程本质上有助于我们遵守PEP8的风格指南。现在,你可以在你的项目中实施linting,你可以探索许多可用的linting工具,并确定哪种工具最能补充,并增强你的Python开发方法。

更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

  • 发表于 2025-01-08 09:38
  • 阅读 ( 35 )
  • 分类:Python开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
小柒
小柒

1658 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1658 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章