Python代碼分析工具:PyCheck
- 2020 年 1 月 6 日
- 筆記
1 概述
PyChecker是Python代碼的靜態分析工具,它能夠幫助查找Python代碼的bug,而且能夠對代碼的複雜度和格式等提出警告。
PyChecker可以工作在多種方式之下。首先,PyChecker會導入所檢查文件中包含的模塊,檢查導入是否正確,同時檢查文件中的函數、類和方法等。
PyChecker可以檢查出來的問題有如下幾種:
- 全局量沒有找到,比如沒有導入模塊
- 傳遞給函數、方法、構造器的參數數目錯誤
- 傳遞給內建函數和方法的參數數目錯誤
- 字符串格式化信息不匹配
- 使用不存在的類方法和屬性
- 覆蓋函數時改變了簽名
- 在同一作用域中重定義了函數、類、方法
- 使用未初始化的變量
- 方法的第一個參數不是self
- 未使用的全局量和本地量(模塊或變量)
- 未使用的函數/方法的參數(不包括self)
- 模塊、類、函數和方法中沒有docstring
2 使用
從官網下載最新版本的PyChecker之後,解壓安裝即可:python setup.py install
首先可以在解壓後的目錄中測試一番:
[root@rango pychecker-0.8.19]# pychecker setup.py Processing module setup (setup.py)… Warnings… [system path]/distutils/command/bdist_wininst.py:271: Statement appears to have no effect [system path]/distutils/command/build_scripts.py:80: No class attribute (dry_run) found [system path]/distutils/command/build_scripts.py:97: No class attribute (dry_run) found [system path]/distutils/command/build_scripts.py:120: (file) shadows builtin [system path]/distutils/command/build_scripts.py:121: No class attribute (dry_run) found [system path]/distutils/command/install_data.py:62: (dir) shadows builtin [system path]/distutils/command/install_data.py:64: (dir) shadows builtin [system path]/distutils/command/install_data.py:66: (dir) shadows builtin [system path]/distutils/command/install_scripts.py:52: (file) shadows builtin [system path]/distutils/command/install_scripts.py:53: No class attribute (dry_run) found 19 errors suppressed, use -#/–limit to increase the number of errors displayed
可以看到,檢查的結果將setup.py依賴的一些文件中的語法錯誤或者警告都列舉出來了,使用–only參數可以只檢查自身的語法問題:
[root@rango pychecker-0.8.19]# pychecker –only setup.py Processing module setup (setup.py)… Warnings… None
參數和選項說明:pychecker [options] 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 [options] 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 id |occurrences | +========================+============+ |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 的 id, 然後通過 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. [txt|html] 命名的文件中,如果有 report 的話,輸出到名為 pylint_global.[txt|html] 的文件中。默認是輸出到屏幕上不輸出到文件里。
-f <format>, --output-format=<format>
設置輸出格式。可以選擇的格式有 text, parseable, colorized, msvs (visual studio) 和 html, 默認的輸出格式是 text。
--disable-msg=<msg ids>
禁止指定 id 的 message. 比如說輸出中包含了 W0402 這個 warning 的 message, 如果不希望它在輸出中出現,可以使用 --disable-msg= W0402
3.5 高階部分
Pylint可以自定義配置文件,具有高可配置性,高可定製性,並且可以很容易寫小插件來添加功能。
如果運行兩次 Pylint,它會同時顯示出當前和上次的運行結果,從而可以看出代碼質量是否得到了改進。
——游響雲停