jarod8016b 发表于 2018-8-4 07:27:57

Python代码分析工具:PyChecker、Pylint

  1 概述
  PyChecker是Python代码的静态分析工具,它能够帮助查找Python代码的bug,而且能够对代码的复杂度和格式等提出警告。
  PyChecker可以工作在多种方式之下。首先,PyChecker会导入所检查文件中包含的模块,检查导入是否正确,同时检查文件中的函数、类和方法等。
  PyChecker可以检查出来的问题有如下几种:

[*]  全局量没有找到,比如没有导入模块
[*]  传递给函数、方法、构造器的参数数目错误
[*]  传递给内建函数和方法的参数数目错误
[*]  字符串格式化信息不匹配
[*]  使用不存在的类方法和属性
[*]  覆盖函数时改变了签名
[*]  在同一作用域中重定义了函数、类、方法
[*]  使用未初始化的变量
[*]  方法的第一个参数不是self
[*]  未使用的全局量和本地量(模块或变量)
[*]  未使用的函数/方法的参数(不包括self)
[*]  模块、类、函数和方法中没有docstring
  2 使用
  从官网下载最新版本的PyChecker之后,解压安装即可:python setup.py install
  首先可以在解压后的目录中测试一番:
  # pychecker setup.py
  Processing module setup (setup.py)...
  Warnings...
  /distutils/command/bdist_wininst.py:271: Statement appears to have no effect

  /distutils/command/build_scripts.py:80: No>
  /distutils/command/build_scripts.py:97: No>  /distutils/command/build_scripts.py:120: (file) shadows builtin

  /distutils/command/build_scripts.py:121: No>  /distutils/command/install_data.py:62: (dir) shadows builtin
  /distutils/command/install_data.py:64: (dir) shadows builtin
  /distutils/command/install_data.py:66: (dir) shadows builtin
  /distutils/command/install_scripts.py:52: (file) shadows builtin

  /distutils/command/install_scripts.py:53: No>  19 errors suppressed, use -#/--limit to increase the number of errors displayed
  可以看到,检查的结果将setup.py依赖的一些文件中的语法错误或者警告都列举出来了,使用--only参数可以只检查自身的语法问题:
  # pychecker --only setup.py
  Processing module setup (setup.py)...
  Warnings...
  None
  参数和选项说明:pychecker file1.py file2.py ...
  --only      只给出命令行的文件的警告,默认为no
  -#,--limit    显示的最大警告数,默认为10
  --no-shadowbuiltin    检查是否有变量覆盖了内建变量,默认为off
  -q,--stdlib      忽略标准库的文件的警告,默认为off
  -T,--argsused    未使用的方法/函数的关键字,默认为on
  修改默认配置和行为:.pycheckrc文件,该文件放置在$HOME目录下,--rcfile选项可以生成一份默认的配置文件。
  要禁止一些模块/函数/类/方法的警告信息,可以在.pycheckrc文件中定义一个禁止字典,键类似:
  ‘module’,‘module.function’,'module.class'等。
  或者直接在代码中定义:
  __pychecker__ = 'no-namedargs maxreturns=0 unsednames=foo,bar'
  其中__pychecker__格式的值和在禁止字典中的值是一样的
  在代码文件中导入PyChecker模块及使用:
  import pychecker.checker
  这将会检查所有在PyChecker之后导入的模块,之前的不检查。
  如果不能传递命令行参数,可以使用:
  os.environ['PYCHECKER'] = 'command line options here'
  等价于在shell环境中设置PYCHECKER:
  PYCHECKER='no-namedargs maxreturns=0' /path/to/your/program
  要关闭警告,可以在导入PyChecker之前,加上:
  os.environ['PYCHECKER_DISABLED'] = 1
  等价于在shell环境中设置PYCHECKER_DISABLED:
  PYCHECKER_DISABLED=1 /path/to/your/program
  3 Pylint
  相比于PyChecker,Pylint是一个高阶的Python代码分析工具,它分析Python代码中的错误,查找不符合代码风格标准(Pylint 默认使用的代码风格是 PEP 8)和有潜在问题的代码。目前 Pylint 的最新版本是 pylint-1.2.1。可以检查一行代码的长度、变量名是否符合规范等。运行两次可以看出代码是否改进,分数是否有所提高,10分满分。
  3.1 安装Pylint
  从官网下载最新版本,解压之后,执行:python setup.py install,安装完毕
  3.2 使用Pylint
  命令行:pylint module_or_package
  图形化:pylint-gui
  注解:pylint-gui依赖tkinter,安装tkinter:yum install -y tkinter
  3.3 输出信息
  Message_Type
  (C) convention惯例。违反了编码风格标准
  (R) refactor重构。写得非常糟糕的代码。
  (W) warning警告。某些 Python 特定的问题。
  (E) error错误。很可能是代码中的错误。
  (F) 致命错误。阻止 Pylint 进一步运行的错误。
  Report
  report报告用来统计一些message类型的数量,模块的依赖等。检查module的数量,每个module错误和警告所占百分比
  Global evaluation
  代码评分
  Global evaluation
  -----------------
  Your code has been rated at 7.98/10
  示例:检查pylint-1.2.1目录下的setup.py文件:pylint setup.py
  No config file found, using default configuration
  ************* Module pylint-1.2.1.setup
  I:3, 0: Locally disabling reimported (W0404) (locally-disabled)
  I:3, 0: Locally disabling redefined-builtin (W0622) (locally-disabled)
  I:3, 0: Locally disabling pointless-except (W0704) (locally-disabled)
  I:3, 0: Locally disabling unused-argument (W0613) (locally-disabled)
  I: 42, 0: Locally disabling no-name-in-module (E0611) (locally-disabled)
  C: 11, 0: Line too long (81/80) (line-too-long)
  C:179, 0: Wrong hanging indentation.
  'pylint = pylint:run_pylint',
  |   ^ (bad-continuation)
  C:180, 0: Wrong hanging indentation.
  'pylint-gui = pylint:run_pylint_gui',
  |   ^ (bad-continuation)
  C:181, 0: Wrong hanging indentation.
  'epylint = pylint:run_epylint',
  |   ^ (bad-continuation)
  C:182, 0: Wrong hanging indentation.
  'pyreverse = pylint:run_pyreverse',
  |   ^ (bad-continuation)
  C:183, 0: Wrong hanging indentation.
  'symilar = pylint:run_symilar',
  |   ^ (bad-continuation)
  C:184, 0: Wrong hanging indentation.
  ]}
  |   |   ^ (bad-continuation)
  C:199, 0: Wrong continued indentation.
  'build_py': build_py},
  | ^ (bad-continuation)
  C:202, 0: No space allowed before :
  if __name__ == '__main__' :
  ^ (bad-whitespace)
  F: 54, 0: Unable to import '__pkginfo__' (import-error)
  C: 57, 0: Invalid constant name "distname" (invalid-name)
  C: 58, 0: Invalid constant name "scripts" (invalid-name)
  C: 59, 0: Invalid constant name "data_files" (invalid-name)
  C: 60, 0: Invalid constant name "subpackage_of" (invalid-name)
  C: 61, 0: Invalid constant name "include_dirs" (invalid-name)
  C: 62, 0: Invalid constant name "ext_modules" (invalid-name)
  C: 63, 0: Invalid constant name "install_requires" (invalid-name)
  C: 64, 0: Invalid constant name "dependency_links" (invalid-name)
  C: 71, 4: Invalid constant name "long_description" (invalid-name)
  C: 73, 4: Invalid constant name "long_description" (invalid-name)
  C:139,24: Invalid variable name "n" (invalid-name)
  W:138,30: Unused variable 'dirnames' (unused-variable)
  R:105, 0: Too many public methods (32/20) (too-many-public-methods)
  Report
  ======
  109 statements analysed.
  Statistics by type
  ------------------
  +---------+-------+-----------+-----------+------------+---------+
  |type   |number |old number |difference |%documented |%badname |
  +=========+=======+===========+===========+============+=========+
  |module   |1      |1          |=          |100.00      |0.00   |
  +---------+-------+-----------+-----------+------------+---------+
  |class    |1      |1          |=          |100.00      |0.00   |
  +---------+-------+-----------+-----------+------------+---------+
  |method   |2      |2          |=          |100.00      |0.00   |
  +---------+-------+-----------+-----------+------------+---------+
  |function |3      |3          |=          |100.00      |0.00   |
  +---------+-------+-----------+-----------+------------+---------+
  Duplication
  -----------
  +-------------------------+------+---------+-----------+
  |                         |now   |previous |difference |
  +=========================+======+=========+===========+
  |nb duplicated lines      |0   |0      |=          |
  +-------------------------+------+---------+-----------+
  |percent duplicated lines |0.000 |0.000    |=          |
  +-------------------------+------+---------+-----------+
  Messages by category
  --------------------
  +-----------+-------+---------+-----------+
  |type       |number |previous |difference |
  +===========+=======+=========+===========+
  |convention |20   |20       |=          |
  +-----------+-------+---------+-----------+
  |refactor   |1      |1      |=          |
  +-----------+-------+---------+-----------+
  |warning    |1      |1      |=          |
  +-----------+-------+---------+-----------+
  |error      |0      |0      |=          |
  +-----------+-------+---------+-----------+
  Messages
  --------
  +------------------------+------------+

  |message>  +========================+============+
  |invalid-name            |11          |
  +------------------------+------------+
  |bad-continuation      |7         |
  +------------------------+------------+
  |locally-disabled      |5         |
  +------------------------+------------+
  |unused-variable         |1         |
  +------------------------+------------+
  |too-many-public-methods |1         |
  +------------------------+------------+
  |line-too-long         |1         |
  +------------------------+------------+
  |import-error            |1         |
  +------------------------+------------+
  |bad-whitespace          |1         |
  +------------------------+------------+
  Global evaluation
  -----------------
  Your code has been rated at 7.98/10 (previous run: 7.98/10, +0.00)
  Raw metrics
  -----------
  +----------+-------+------+---------+-----------+
  |type      |number |%   |previous |difference |
  +==========+=======+======+=========+===========+
  |code      |133    |68.56 |133      |=          |
  +----------+-------+------+---------+-----------+
  |docstring |18   |9.28|18       |=          |
  +----------+-------+------+---------+-----------+
  |comment   |28   |14.43 |28       |=          |
  +----------+-------+------+---------+-----------+
  |empty   |15   |7.73|15       |=          |
  +----------+-------+------+---------+-----------+
  External dependencies
  ---------------------
  ::
  setuptools (pylint-1.2.1.setup)
  \-command
  \-install_lib (pylint-1.2.1.setup)
  3.4 常用命令行参数和选项

[*]  -h,--help
  显示所有帮助信息。

[*]  --generate-rcfile
  可以使用 pylint --generate-rcfile 来生成一个配置文件示例。可以使用重定向把这个配置文件保存下来用做以后使用。也可以在前面加上其它选项,使这些选项的值被包含在这个产生的配置文件里。如:pylint --persistent=n --generate-rcfile > pylint.conf,查看 pylint.conf,可以看到 persistent=no,而不再是其默认值 yes。

[*]  --rcfile=<file>
  指定一个配置文件。把使用的配置放在配置文件中,这样不仅规范了自己代码,也可以方便地和别人共享这些规范。

[*]  -i <y_or_n>, --include-ids=<y_or_n>
  在输出中包含 message 的>pylint --help-msg=<msg-id>来查看这个错误的详细信息,这样可以具体地定位错误。

[*]  -r <y_or_n>, --reports=<y_or_n>
  默认是 y, 表示 Pylint 的输出中除了包含源代码分析部分,也包含报告部分。

[*]  --files-output=<y_or_n>
  将每个 module /package 的 message 输出到一个以 pylint_module/package. 命名的文件中,如果有 report 的话,输出到名为 pylint_global. 的文件中。默认是输出到屏幕上不输出到文件里。

[*]  -f <format>, --output-format=<format>
  设置输出格式。可以选择的格式有 text, parseable, colorized, msvs (visual studio) 和 html, 默认的输出格式是 text。

[*]  --disable-msg=<msg>
  禁止指定>--disable-msg= W0402
  3.5 高阶部分
  Pylint可以自定义配置文件,具有高可配置性,高可定制性,并且可以很容易写小插件来添加功能。
  如果运行两次 Pylint,它会同时显示出当前和上次的运行结果,从而可以看出代码质量是否得到了改进。
  ——游响云停
页: [1]
查看完整版本: Python代码分析工具:PyChecker、Pylint