当前位置:   article > 正文

Python代码规范:企业级代码静态扫描-代码规范、逻辑、语法、安全检查,以及代码规范自动编排(1)_python 静态检查

python 静态检查

适用于企业实际使用Python或Python框架(Tornado、Django、Flask等)开发的项目作为扫描目标,进行代码规范、逻辑、语法、安全检查。代码风格规范主要有几个方面:命名规范、语言规范、格式规范。其中大部分命名规范和语言规范主要需要开发者编写代码的时候遵循。规范检测方面涉及到的主要工具:pylintflake8、pyproject-flake8、pyflakes、mypy、autoflake、yapf、black。

代码规范自动编排,针对如未使用的包,定义了未使用的变量,每行字符数过长,内置包、第三方包、自定义包的导入顺序等这些问题,通过工具自动化进行编排。代表性的工具:isort、autopep8。

代码风格:使用PEP8规范进行代码编写,包括注释、变量名、函数名等的命名规范。

代码结构:基于模块化设计的思想进行代码的组织,避免代码的冗余和不必要的重复。

语法检查:使用静态代码检查工具进行代码检查,确保代码不会出现常见的语法错误。

逻辑检查:通过对代码进行测试和验证,确保代码的逻辑正确性,一旦发现问题应及时进行修复和处理。

安全检查:避免在代码中出现潜在的安全漏洞,例如不安全的输入输出处理等。

自动编排:使用自动代码格式化工具,如Black和YAPF等,统一代码风格和排版,提高代码的可读性和易维护性。

本篇将总结实际项目开发中Python代码规范检查、自动编排的一些工具,特点,使用方法,以及如何在Pycharm中集成这些工具。限于篇幅,本篇将总结pylint、pyproject-flake8、pyflakes、flake8、mypy这一部分的工具。下一篇总结autoflake、yapf、black、isort、autopep8代码规范和自动编排工具。

常见静态扫描工具

常见的Python企业级代码静态扫描工具包括:

  1. Flake8:检查代码规范、语法等。合并了 Pylint、Pyflakes 和 pep8(Python 代码风格规范)的检查,可以同时进行多种检查。
  2. PyLint:检查代码规范、语法、命名、代码重复率等。可以自定义规则来进行检查。
  3. Pyflakes:用于检查 Python 代码的语法和语义错误,比 Pylint 更快,但检查范围较小。
  4. Bandit:检查代码中的安全漏洞。如密码泄露、SQL 注入等。
  5. Prospector:综合使用Flake8、PyCodeStyle等工具做代码规范检查。
  6. Black:用于自动编排 Python 代码,可以保证代码的格式一致性,并根据最佳实践的规则进行排版。
  7. pyproject-flake8:是一个基于flake8的插件,可以使用pyproject.toml文件来配置flake8的规则和插件。pyproject.toml是Python项目的全局配置文件,可以用来指定项目依赖、Python版本、运行命令等信息。
  8. mypy:是一个静态类型检查器,主要用于检查Python代码中的类型错误。它可以在运行代码之前捕获一些类型错误,提高代码的可读性和可维护性。mypy需要在代码中添加类型注解来工作,但不会影响代码的运行。
  9. autoflake:是一个自动化代码清理工具,可以删除Python代码中未使用的导入、函数和变量等。它还可以检查代码中的一些常见错误并予以修复。使用autoflake可以减少代码中的冗余和错误,提高代码的可读性和可维护性。
  10. yapf:是一个Python代码格式化工具,可以自动对代码进行排版和格式化。它支持许多不同的排版风格,并可以根据用户的偏好进行自定义。使用yapf可以使代码风格统一,减少人工调整代码格式的工作量。
  11. PyCharm:IDE集成了众多代码检查功能,如PEP规范、语法错误等。以及可以将上述的工具集成到IDE External Tools中。

在进行代码检查前,需要事先定义好团队内的代码规范、架构设计等约束条件。同时,应该将代码检查纳入到持续集成流程中,每次代码提交时自动触发检查。

在代码检查后,可以通过代码规范自动编排工具进行格式化和调整,确保整个代码库的风格一致性和易读性。常用的工具包括YAPF、autopep8等。

pylint

介绍

https://www.pylint.org/

Pylint 是一个检查违反 PEP 8 规范和常见错误的库。它在一些流行的编辑器和 IDE 中都有集成,也可以单独从命令行运行。

Pylint主要的功能就是用于编码风格的检验,默认情况下 Pylint 会以 PEP-8为标准,如果写的代码不符合 PEP-8编码规范,它就会给你报错。

可以通过修改 pylint 的配置文件,修改它检查的方式,从而使它遵守其他的编码规范,比如可以强行让变量名函数名都变成驼峰命名法。

使用 Pylint 方便团队形成统一的编码规范。

是一个Python代码分析工具,它分析 Python 代码中的错误,查找不符合代码风格标准(Pylint 默认使用的代码风格是 PEP 8)和有潜在问题的代码。比如检查一行代码的长度,变量名是否符合命名标准,一个声明过的接口是否被真正实现等等。

安装&配置

安装pip install pylint

  1. Pycharm中设置

Arguments:$FilePath$

  1. Pycharm中指定配置文件方式

  1. Pycharm中添加参数屏蔽自定类型的检查

disable=W,E,R,C

使用

运行 pylint [options] path/to/dir 或者 pylint [options] path/to/module.py 就可以在命令行中使用 Pylint,它会向控制台输出代码中违反规范和出现错误的地方。

还可以使用 pylintrc 配置文件来自定义 Pylint 对哪些代码错误进行检查。

命令行参数

  • -h, –help

显示所有帮助信息。

  • --generate-rcfile

可以使用 pylint --generate-rcfile 来生成一个配置文件示例。可以使用重定向把这个配置文件保存下来用做以后使用。

pylint --generate-rcfile > pylint.conf

  • --rcfile=<xx.conf>

指定一个配置文件运行pylint。把使用的配置放在配置文件中,这样不仅规范了自己代码,也可以方便地和别人共享这些规范。

pylint --rcfile=pylint.conf dw.py

  • --reports=<y_or_n>

默认是 n, 表示 Pylint 的输出中除了包含源代码分析部分,也包含报告部分。

pylint --rcfile=pylintrc.conf --reports=y main.py

报告中安装上述的格式生成检查结果,W代表生成的检查级别,级别分为4种:error, warning, refactor, convention;可以根据首字母来对应相应的级别。“10, 0” 代表告警所在源码文件中的行号和列号。“Unused import help"表述问题的详细信息。”(unused-import)为问题的消息ID信息。

下面的信息是按照消息的类别进行分类,对4种级别的告警信息进行汇总:

  • --help-msg=

获取告警帮助信息。

如需对某告警类型获取帮助信息,可以使用"pylint --help-msg "命令来获取:

pylint --help-msg=C0114

在输出中包含 message 的 id, 然后通过 pylint --help-msg=来查看这个错误的详细信息,这样可以具体地定位错误。

  • --output-format=

设置输出格式。可以选择的格式有 text, parseable, colorized, msvs (visual studio) , 默认的输出格式是 text。

pylint --output-format=msvs external.py

  • xx.txt

将每个 module /package 的 message 输出到一个以 pylint_module/package.txt命名的文件中,如果有 report 的话,输出到名为 pylint_global.[txt|html] 的文件中。默认是输出到屏幕上不输出到文件里。

pylint --output-format=msvs external.py > test.txt

Pylint的输出

Pylint的默认输出格式是原始文本(raw text)格式 ,可以通过-f ,--output-format= 来指定别的输出格式如html等等。在Pylint的输出中有如下两个部分:源代码分析部分和报告部分。

源代码分析部分:

对于每一个 Python 模块,Pylint 的结果中首先显示一些"*"字符 , 后面紧跟模块的名字,然后是一系列的 message, message 的格式如下:

MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE

MESSAGE_TYPE 有如下几种:

(C) 惯例。违反了编码风格标准

(R) 重构。写得非常糟糕的代码。

(W) 警告。某些 Python 特定的问题。

(E) 错误。很可能是代码中的错误。

(F) 致命错误。阻止 Pylint 进一步运行的错误。

忽略某个文件不进行检查

external.py不检查,在文件中设置: # pylint: skip-file

  1. # pylint: skip-file
  2. from pysdk.first_layer import BaseLayer
  3. class Events(BaseLayer):
  4. def __init__(self):
  5. # pylint: disable=C0115
  6. super(Events, self).__init__()
  7. class Metrics(BaseLayer):
  8. def __init__(self):
  9. super(Metrics, self).__init__()

忽略文件中执行类型(C,R,W,E,F)不进行检查

external.py’W’类型不检查,在文件中设置: # pylint: disable=W

  1. # pylint: disable=W
  2. from pysdk.first_layer import BaseLayer
  3. class Events(BaseLayer):
  4. def __init__(self):
  5. super(Events, self).__init__()
  6. class Metrics(BaseLayer):
  7. def __init__(self):
  8. super(Metrics, self).__init__()

忽略文件中某个函数执行类型(C,R,W,E,F)不进行检查

external.py’W,R,E’类型不检查,在文件中类下函数或普通函数下设置: # pylint: disable=W,E,R

  1. from pysdk.first_layer import BaseLayer
  2. class Events(BaseLayer):
  3. def __init__(self):
  4. # pylint: disable=W,R,E
  5. super(Events, self).__init__()
  6. def __init__(self):
  7. super(Events, self).__init__()
  8. class Metrics(BaseLayer):
  9. def __init__(self):
  10. super(Metrics, self).__init__()

 

忽略文件中某个类执行类型(C,R,W,E,F)不进行检查

external.py’W,R,E’类型不检查,在文件中类下面设置: # pylint: disable=C,F,W,E,R

  1. from pysdk.first_layer import BaseLayer
  2. class Events(BaseLayer):
  3. # pylint: disable=C,R,W,E,F
  4. def __init__(self):
  5. super(Events, self).__init__()
  6. def __init__(self):
  7. super(Events, self).__init__()
  8. class Metrics(BaseLayer):
  9. def __init__(self):
  10. super(Metrics, self).__init__()

忽略no-member的提示

 

代码处修改 # pylint: disable=no-member

pylint --disable=no-member ...

在命令行中使用pylint: disable=W

  • 不禁用指定类型

pylint + 目标项目或者文件

编写测试代码文件

执行pylint

执行结果

如果对代码进行规范整改,对整改后的代码再次扫描,则会看到无任何检测状态,评分为10份

或命令行中执行pylint pylint_test.py

  • 禁用W类型

pylint --disable=W external.py

配置文件配置

在项目根目录下生成配置文件pylintrc.conf

pylint --generate-rcfile > pylintrc.conf

pylint --persistent=n --generate-rcfile > pylintrc.conf

  • 携带配置文件,针对单个文件的扫描

pylint --rcfile=pylintrc.conf manage.py

  • 对指定项进行disable

配置禁止warning,配置禁止检查指定项

pylint的几种状态:Error(错误) Warning(警告) Refactor(重构) Convention(规范)

--disable=W,E,R,C

--disable=E,R,C

--disable=E,R

对R0801项进行disable之后,再次扫描则会看到不会再输出不符合的结果

  • pylint设置每行检测字符数

针对每行字符数的修改,默认100

注意:重命名pylint.conf.pylintrc,即不需要每次执行都带上--rcfile参数。

  • 对整个项目扫描

在项目根目录下右击选择pylint执行

使用pylint有如下几种提示级别Error(错误)、Warning(警告)、Refactor(重构)、Convention(规范)。

输出的结果包括:与规范冲突的位置(行列)、违反的规范编号以及具体的内容提示,会针对检测结果给出一个评分,总分10分。

从检查信息可以看到,上述代码缺少模块注释(Missing module docstring)以及函数注释(Missing function docstring),函数名不符合蛇形命名规范(全由小写字母和下划线组成,在两个单词之间用下滑线连接)等。

参考文档

  1. 官方文档:http://pylint.pycqa.org/en/latest/user_guide/output.html
  2. pylint:https://pylint.readthedocs.io/en/latest/user_guide/usage/run.html

pyproject-flake8

介绍

pyproject-flake8是一个Python代码规范检查工具。它基于Flake8,可以帮助开发者遵守Python代码规范,提高代码质量。

pyproject-flake8可以检查一些常见的编码问题,如不使用的变量、未使用的导入、格式化字符串错误等等。此外,它还可以检查PEP8规范,包括缩进、空格、换行符等等。

使用pyproject-flake8可以提高开发效率,减少代码中的错误和警告,使代码更加清晰易读,有助于维护和升级。是Python开发推荐的一款工具,它可以帮助开发者创建具有一致性、清晰易读和高质量的代码。

安装&配置

pyproject-flake8是一个用于代码静态分析和错误检查的工具,它可以通过检查Python代码中的语义和规范来发现潜在的问题或错误。

1. 安装pyproject-flake8:可以使用pip包管理器来安装。

  1. ```
  2. pip install pyproject-flake8
  3. ```

2. 创建一个pyproject.toml文件:在项目的根目录下创建一个名为pyproject.toml的文件,并添加如下内容:

  1. [tool.flake8]
  2. max-line-length = 88
  3. extend-ignore = E203,E501,W503
  4. exclude =
  5. .git
  6. __pycache__
  7. build
  8. dist
  9. .vscode

上述配置设置了最大行长度,忽略了一些常见的错误和警告,例如E203、E501、W503等,以及排除了一些目录。

或集成black,isort,flake8工具的详细配置如下

  1. [tool.black]
  2. line-length = 120
  3. include = '\.pyi?$'
  4. skip-string-normalization = 'true'
  5. exclude = '''
  6. /(
  7. \.git
  8. | \.hg
  9. | \.mypy_cache
  10. | \.tox
  11. | \.venv
  12. | _build
  13. | buck-out
  14. | build
  15. | dist
  16. | iam
  17. )/
  18. '''
  19. [tool.isort]
  20. profile = "black"
  21. [tool.flake8]
  22. ignore = "C901,E203,W503,F405,E402"
  23. max-line-length = 120
  24. max-complexity = 25
  25. format = "pylint"
  26. exclude = "*migrations*,*.pyc,.git,__pycache__.tox,docs,old,build,dist,*.egg-info,.cache,.eggs,env,ebpack,cripts/*,am/*,onf/*,larm_backends/tests/*,/parsetab.py"

使用

运行pyproject-flake8:在终端中使用以下命令运行pyproject-flake8:

```shell

# 检查整个项目

flake8 .

# 检查指定文件

flake8 example.py

```

以上命令的执行将输出代码中存在的错误和警告信息,并显示在终端中。即可成功使用pyproject-flake8来检查Python代码的问题和错误,以便在开发过程中更加高效地进行检查和调试。

pyflakes

介绍

可以用Pyflakes来检查代码是不是有语法错误或者逻辑错误。

Pyflakes 不会检查代码的风格,所以被Pylint报了一大堆错的文件,用Pyflakes来检查,它只会报三个错:

  1. 引入但没有用到的模块
  2. 变量定义了但是没有使用
  3. 如果有语法错误,那么 Pyflakes 就能成功发现。

特点:

  1. 用Pyflakes分析代码风格和寻找违法PEP-8编码规范的地方;
  2. Pyflakes的另一优势是分析速度快,但它能报告的错误类型是相当有限的。
  3. Pyflakes是静态分析的工具,所以对于像'1' + 1这种异常是无法检查出来的。

安装&配置

使用PIP安装:pip install pyflakes

使用

1. 在命令行中运行以下命令,可以检查 Python 文件中的语法错误和未使用的变量:

pyflakes filename.py

其中, filename.py 表示要检查的 Python 文件的名称。

2. 如果要检查整个项目,请运行以下命令:

pyflakes project_directory

其中, project_directory 是要检查的项目目录的绝对或相对路径。

3. 与其它工具集成

Pyflakes 还可以与其他Python工具集成,如 Flake8 和 PyLint。这些工具可以通过安装相应的插件来使用 Pyflakes 进行代码检查。

例如,使用Flake8:

pip install flake8

flake8 --select=F401 filename.py

其中, --select=F401 表示仅检查未使用的变量,filename.py 表示要检查的 Python 文件的名称。

flake8

介绍

Flake8 是由Python官方发布的一款辅助检测Python代码是否规范的工具,相对于目前热度比较高的Pylint来说,Flake8检查规则灵活,支持集成额外插件,扩展性强。可以编写程序实现代码规范性检测。

Pylint 类似,Flake8 允许通过配置文件来自定义检查的内容。它有非常清晰的文档,包括一些有用的提交钩子,可以将自动检查代码纳入到开发工作流程之中。

Flake8 也可以集成到一些流行的编辑器和 IDE 当中。

Flake8相当于 Pyflakes + Pylint 的合体。

Flake8 包含三个代码库,是“将 PEP 8、Pyflakes(类似 Pylint)、McCabe(代码复杂性检查器)和第三方插件整合到一起,以检查 Python 代码风格和质量的一个 Python 工具”。

  1. PyFlakes
  2. pycodestyle
  3. Ned Batchelder’s McCabe script

Ned Batchelder's McCabe script是一个Python代码分析工具,用于计算一个函数的McCabe复杂度。 McCabe复杂度是一种衡量代码复杂度的指标,它基于流程图中的节点和分支数量。 Batchelder的脚本使用AST(抽象语法树)分析Python函数,并计算其McCabe复杂度。此工具可用于评估代码的可维护性和理解复杂性。

安装&配置

使用PIP安装:pip install flake8

  1. PyCharm中配置Flake8

name:Flake8(随便写一个)

Program: `$PyInterpreterDirectory$/python`

Arguments: -m flake8 --max-line-length=130 --exclude venv,migrations $ProjectFileDir$ (可以根据自己的需求进行配置)

Working directory: `$ProjectFileDir$`

使用

PyCharm中使用

在需要检查的项目中,右键选择Flake8即可。

命令行中使用

如果要检查整个项目,直接在项目根目录下执行flake8指令

flake8 [options] path/to/dir 

  1. 针对单个文件

flake8 [options] path/to/module.py 

flake8 pylint_test.py

使用配置文件对项目进行扫描

参考文档

  1. flake8配置:Configuring Flake8 — flake8 6.0.0 documentation
  2. flake8钩子:Using Version Control Hooks — flake8 6.0.0 documentation
  3. https://flake8.pycqa.org/en/latest/
  4. https://github.com/pycqa/flake8/blob/main/docs/source/index.rst
  5. https://pylint.readthedocs.io/en/latest/

mypy

介绍

mypy是一个代码静态类型检查器。帮助开发者更早地发现代码中的类型错误,从而减少不必要的调试和维护时间。

Mypy让动态语言 Python 拥有静态类型检查的能力。通过使用Python的类型标注功能,Mypy 能够确保变量类型始终如一,始终是定义的那样,不会因为中途的某次赋值,把一个列表变成了字符串。

Mypy能正常识别出类似于字符串与数字相加这种错误,无论是直接 hard code 写的还是字符串变量加上整型变量。在代码中声明了a_list是一个只包含数字的列表,当传入一个字符串的时候就会报错。

mypy具有以下特点:

  1. 静态类型检查:mypy支持Python 3的类型注解,通过检查这些注解,可以在编译时发现代码中的类型错误。
  2. 功能强大:mypy支持多种类型,包括基本类型、容器类型、自定义类型等,并且可以支持函数重载、泛型等高级特性。
  3. 可扩展性:mypy可以扩展自定义(插件)类型和检查规则,使其适应更多的使用场景。
  4. 可移植性:mypy可以在多种平台上运行,包括Linux、macOS、Windows等。
  5. 可与其他工具集成:mypy可以与其他工具集成,如IDE、静态分析工具等,提升开发效率和代码质量。
  6. mypy支持Python 2Python 3

安装&配置

使用pip install mypy命令来安装mypy

使用

  1. 创建Python示例代码

创建一个Python文件,并使用类型注释描述变量和函数的类型信息。

  1. def add_numbers(a, b):
  2. return a + b
'
运行

为该函数添加类型注释
 

  1. def add_numbers(a: int, b: int) -> int:
  2. return a + b
'
运行

“a”和“b”的类型均为“int”,并且该函数将返回一个“int”的值。

  • 检查类型错误

在终端中运行mypy命令来检查该文件中是否存在类型错误。例如:mypy myfile.py。

  • 解决问题

如果mypy发现了类型错误,需要改变代码来解决这些问题。

如果代码没有任何类型错误,则mypy将不会输出任何内容。

  • 持续监测

在编辑器中配置mypy插件,以便在编写代码时持续检查类型错误。

  • 集成到编译流程

将mypy集成到编译流程中,以确保代码可以顺利地通过类型检查。

参考文档

  1. mypy 1.1.1 documentation


 输入才有输出,吸收才能吐纳。——码字不易

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号