使用PyLint分析評估程式碼質量

2022-12-08 15:00:19

什麼是PyLint

PyLint是一款用於評估Python程式碼質量的分析工具,它誕生於2003年,其最初十年的主要作者和維護者是Sylvain Thénault。PyLint可以用來檢查程式碼是否錯誤、是否符合編碼規範(它預設使用的編碼規範是PEP 8),在分析程式碼後PyLint將會輸出一段資訊,內容包括在程式碼中檢查到的警告和錯誤,如果執行兩次,它將會輸出兩次的統計資訊,以便使用者分析程式碼是否得到改進。PyLint的特性是報告儘可能少的錯誤,但是它會輸出非常多的警告資訊,所以建議在程式提交之前或者想要整理程式碼時使用PyLint,這樣可以忽略掉大量的無效警告。

自PyLint 1.4起,PyLint只支援Python 2.7+和Python 3.3+。

安裝PyLint

在命令列介面執行如下程式碼,即可安裝PyLint:

pip install pylint

在命令列介面執行如下程式碼,即可查詢PyLint的安裝路徑:

where pylint

呼叫PyLint

在命令列中呼叫

分析Python包或者Python模組

pylint [options] module_or_package

分析Python檔案

pylint [options] mymodule.py

並行分析Python檔案

pylint -j 4 mymodule1.py mymodule2.py mymodule3.py mymodule4.py

上述語句將產生4個並行的PyLint子程序來對所需的四個檔案並行檢查,PyLint發現問題後不會立即顯示,待所有模組檢查完畢後才會顯示。其中,引數-j用於指定所需的PyLint子程序數量,預設值為1。

常用的命令列選項

  • --version:顯示PyLint以及Python的版本;

    使用範例:

    pylint --version
    
  • -h, --help :顯示幫助資訊;

    使用範例:

    範例一:
    pylint -h
    範例二:
    pylint --help
    
  • -ry:顯示各項資訊的報表統計;

    使用範例:

    pylint -ry mymodule.py
    
  • --generate-rcfile:生成設定資訊範例;

    使用範例:

    ## 將persistent修改為n,並將設定資訊儲存至pylint.conf檔案中
    pylint --persistent=n --generate-rcfile > pylint.conf 
    
  • --rcfile=<file> :指定所使用的的組態檔;

    使用範例:

    pylint --rcfile=pylint.conf mymodule.py 
    
  • --persistent=y_or_n:是否使用Pickle儲存上次結果;

    使用範例:

    pylint --persistent=y mynodule.py
    
  • --output-format=<format>:指定輸出格式( parseable, colorized, msvs);

    使用範例:

    pylint --output-format=parseable mymodule.py
    
  • --msg-template=<template>:指定輸出內容;

    template引數包括:

    • path:檔案的相對路徑;
    • abspath:檔案的絕對路徑;
    • line:輸出行數;
    • column:輸出列數;
    • module:模組名;
    • obj : 模組中的物件(如果有的話) ;
    • msg :資訊文字;
    • msg_id :資訊編號;
    • symbol :資訊的符號名稱;
    • C:資訊類別;

    使用範例:

    pylint --msg-template='{msg_id}:{line:3d}:{msg}' mymodule.py
    
  • --list-msgs:生成pylint的警告列表;

    使用範例:

    pylint --list-msgs
    
  • --full-documentation : 以reST格式生成pylint的完整檔案。

    使用範例:

    pylint --full-documentation
    

在Python程式中呼叫PyLint

方法一

from pylint import epylint as lint
lint.py_run("mymodule.py --msg-template='{line:3d}:{msg}'")
# 注意,先寫檔名,再寫命令選項,檔名和命令選項通過空格隔開。

方法二

from pylint import epylint as lint
(pylint_stdout, pylint_stderr) = lint.py_run('mymodule.py', return_std=True)
# 注意,返回值型別為StringIO,可以通過read()方法進行讀取。
print(pylint_stdout.read())

關聯PyLint與PyCharm

方法一

  • 進入PyCharm,依次點選: File -> Settings -> Tools -> External Tools,進入下圖頁面;

  • 點選加號,在彈窗中填寫下圖紅色方框中的欄位後,點選OK;

    • Name引數可以填寫pylint;
    • Program引數選擇pylint.exe的路徑,選擇後,Working directory引數將自動補全;
    • Arguments引數根據實際需求點選右側Inser Macros進行選擇即可,範例中選擇檢查當前路徑下的檔案。

  • 依次點選Tools->External Tools->pylint,即可執行PyLint。

方法二

  • 進入PyCharm,依次點選: File -> Settings -> Plugins,進入下圖頁面;

  • 點選Browse repositories,進入下圖頁面;

  • 在左上角搜尋方塊中搜尋pylint,右擊安裝,點選Yes開始下載,之後點選Close,重啟PyCharm後即安裝成功;

  • 依次點選: File -> Settings -> pylint,可根據實際需求進行設定;

  • 執行時,點選左下角pylint即可檢視PyLint輸出,單擊具體輸出內容,可跳轉到相關程式碼行。

PyLint的輸出

原始碼分析

對於每個Python模組,PyLint的輸出格式如下:

  • 第一行將在若干' * '字元后顯示模組名稱;
  • 從第二行起顯示PyLint的輸出,預設的輸出內容格式為——資訊類別:行數:資訊內容 。

資訊類別:

  • R:違反重構標準;
  • C:違反編碼規範;
  • W:警告;
  • E:錯誤;
  • F:致命錯誤,使PyLint無法進一步處理。

PyLint的輸出範例:

************* Module pylint.checkers.format
W: 50: Too long line (86/80)
W:108: Operator not followed by a space
     print >>sys.stderr, 'Unable to match %r', line
            ^
W:141: Too long line (81/80)
W: 74:searchall: Unreachable code
W:171:FormatChecker.process_tokens: Redefining built-in (type)
W:150:FormatChecker.process_tokens: Too many local variables (20/15)
W:150:FormatChecker.process_tokens: Too many branches (13/12)

可以通過pylint --help-msg <msg-id>查詢更多資訊,使用範例:

pylint --help-msg C0115

檢查報告

檢查報告在原始碼分析的後面,每個報告關注專案的特定方面,比如每種類別的資訊數目,模組的依賴關係等等。具體來說,報告中會包含如下的方面:

  • 檢查的模組個數;
  • 對於每個模組,其錯誤和警告在其中所佔的百分比;
  • 對於所有模組,其錯誤和警告的總數量;
  • 檔案中帶有檔案字串的類、函數和模組所佔的百分比;
  • ......

PyLint與PyChecker的區別

PyLint支援PyChecker提供的大部分功能,他們之間一個最主要的區別在於PyLint能夠檢測編碼標準是否規範;其次,PyLint不支援匯入活動模組而PyChecker可以。

PEP 8標準

程式碼佈局

  • 每個縮排級別使用4個空格,連續行使用垂直對齊或者使用懸掛式縮排(額外的4個空格縮排);

  • 空格是首選的縮排方法;

  • 每行最多79個字元;

  • 允許在二元運運算元前後換行,但程式碼需保持一致,對於新程式碼建議在二元運運算元前進行換行;

  • 使用兩個空白行分隔頂層函數和類定義;

  • 類方法定義使用一個空行分隔;

  • 使用額外的空白行來分隔相關邏輯功能;

  • 檔案應該使用UTF-8編碼,且不應該有編碼宣告;

  • 匯入多個庫函數應該分開依次匯入,匯入總是放在檔案的頂部,在任何模組註釋和檔案字串之後,在模組全域性變數和常數之前;匯入應按以下順序進行:標準庫匯入、有關的第三方庫匯入、本地應用程式/庫特定的匯入,每組匯入直接用空行分隔;避免萬用字元匯入(import *)。

字串

  • 單引號字串和雙引號字串相同,但程式碼需保持一致;

  • 對於三引號字串,常用三個雙引號作檔案字串,檔案字串常用在模組的開端用以說明模組的基本功能,或緊跟函數定義的後面用以說明函數的基本功能。

空格

  • 避免使用無關的空格,包括空格內、逗號分號前面等;

  • 避免在行末使用空格;

  • 二元運運算元在兩側使用一個空格;

  • 當用於指示關鍵字引數或預設引數值時,不要在=符號周圍使用空格。

使用尾部逗號(trailing commas)

  • 尾部逗號通常可選,但對於只有一個元素的元組是必選的;

  • 當引數、值等列表期望經常擴充套件時,通常是每個值一行,再加上一個尾部逗號。

註釋

  • 程式碼更改時,相應的註釋也要隨之更改;

  • 註釋應該是完整的語句,第一個單詞應該大寫,除非它是特定識別符號;

  • 塊註釋:縮排到與該程式碼相同的級別,塊註釋的每一行都以#和一個空格開始;

  • 行註釋:對某一語句行進行註釋,註釋應該與語句至少隔開兩個空格,用#和一個空格開始;

  • 對於公共的模組,功能,類和方法需要為其寫檔案字串;

  • 註釋應該是完整的語句,第一個單詞應該大寫,除非它是特定識別符號。

命名約定

  • 命名應該反映其用途而非實現;

  • 不要將字元’l’(小寫字母L),’O’(大寫字母O)或’I’(大寫字母I)作為單個字元變數名稱;

  • 模組名應該使用簡短、全小寫的名字;

  • 類的命名採用駝峰命名法,即每個單詞的首字母大寫;

  • 函數名稱應該是小寫的,為了提高可讀性,必須使用由下劃線分隔的單詞。

參考資料

PyLint官網連結

PEP 8編碼規範