如何使用 Pylint 來規範 Python 程式碼風格

發表於2017-02-27

Pylint 是什麼

Pylint 是一個 Python 程式碼分析工具,它分析 Python 程式碼中的錯誤,查詢不符合程式碼風格標準(Pylint 預設使用的程式碼風格是 PEP 8,具體資訊,請參閱參考資料)和有潛在問題的程式碼。目前 Pylint 的最新版本是 pylint-0.18.1。

  • Pylint 是一個 Python 工具,除了平常程式碼分析工具的作用之外,它提供了更多的功能:如檢查一行程式碼的長度,變數名是否符合命名標準,一個宣告過的介面是否被真正實現等等。
  • Pylint 的一個很大的好處是它的高可配置性,高可定製性,並且可以很容易寫小外掛來新增功能。
  • 如果執行兩次 Pylint,它會同時顯示出當前和上次的執行結果,從而可以看出程式碼質量是否得到了改進。
  • 目前在 eclipse 的 pydev 外掛中也整合了 Pylint。

Pylint 具體介紹

Pylint 的安裝

Pylint 可以用於所有高於或者等於 2.2 的 Python 版本相容。需要 logilab-astng(version >= 0.14)和 logilab-common(version >= 0.13)的包(具體資訊,請參閱 參考資料),如果是 Python 版本低於 2.3,那麼它還需要 optik 包(本文接下來的示例暫不考慮這種情況)。

Pylint 所用到的所有的包的下載地址

logilab-astng 的最新包下載:http://www.logilab.org/856/

logilab-common 的最新包下載:http://www.logilab.org/848/

optik 的包下載:http://optik.sourceforge.net/

Pylint 的最新包下載:http://www.logilab.org/project/pylint

Pylint 在 Linux 上的安裝

1. 在 Linux 上,首先安裝 Python 的包(高於版本 2.2),並在環境變數 $PATH 中新增 Python 可執行檔案的路徑。

2. 下載 Pylint、logilab-astng (version >= 0.14) 和 logilab-common (version >= 0.13) 的包 , 使用 tar zxvf *.tar.gz解壓縮這些包。

3. 依次進入 logilab-astng、logilab-common 和 Pylint 解開的資料夾中,執行命令 Python setup.py install來安裝。

4. 安裝完成後,就可以通過 pylint [options] module_or_package來呼叫 Pylint 了。

Pylint 在 Windows 上的安裝

1. 安裝 Python 的包(高於版本 2.2),右鍵單擊桌面上的我的電腦圖示,選擇屬性,高階,環境變數,在 $PATH 中新增 Python 的安裝路徑,如 C:Python26。

2. 使用解壓縮工具解壓縮所有的包。

3. 開啟命令列視窗,使用 cd依次進入 logilab-astng、logilab-common 和 Pylint 解開的資料夾中,執行命令 python setup.py install來安裝。

4. 安裝完成後,在 Python 的安裝路徑下出現一個 Scripts 資料夾,裡面包含一些 bat 指令碼,如 pylint.bat 等。

5. 為了使呼叫 pylint.bat 的時候不需要輸入完整路徑,在 Python 的安裝目錄下建立 pylint.bat 的重定向檔案,這是一個純文字檔案 pylint.bat,裡面包含 pylint.bat 的實際路徑,如:C:Python26Scriptspylint.bat。

6. 安裝完成後,可以通過 pylint [options] module_or_package來呼叫 Pylint 了。

Pylint 的呼叫

清單 1. Pylint 的呼叫命令

使用 Pylint 對一個模組 module.py 進行程式碼檢查:

  • 1. 進入這個模組所在的資料夾,執行 pylint [options] module.py
    這種呼叫方式是一直可以工作的,因為當前的工作目錄會被自動加入 Python 的路徑中。
  • 2. 不進入模組所在的資料夾,執行 pylint [options] directory/module.py
    這種呼叫方式當如下條件滿足的時候是可以工作的:directory 是個 Python 包 ( 比如包含一個 __init__.py 檔案 ),或者 directory 被加入了 Python 的路徑中。

使用 Pylint 對一個包 pakage 進行程式碼檢查:

  • 1. 進入這個包所在資料夾,執行 pylint [options] pakage。
    這種呼叫方式是一直可以工作的,因為當前的工作目錄會被自動加入 Python 的路徑中。
  • 2. 不進入包所在的資料夾,執行 pylint [options] directory/ pakage。
    這種情況下當如下條件滿足的時候是可以工作的:directory 被加入了 Python 的路徑中。比如在 Linux 上,export PYTHONPATH=$PYTHONPATH: directory。

此外,對於安裝了 tkinter 包的機器,可以使用命令 pylint-gui開啟一個簡單的 GUI 介面,在這裡輸入模組或者包的名字 ( 規則同命令列 ), 點選 Run,Pylint 的輸出會在 GUI 中顯示。

Pylint 的常用命令列引數

  • -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

Pylint 的輸出

Pylint的預設輸出格式是原始文本(raw text)格式 ,可以通過 -f <format>,--output-format=<format> 來指定別的輸出格式如html等等。在Pylint的輸出中有如下兩個部分:原始碼分析部分和報告部分。

原始碼分析部分:

對於每一個 Python 模組,Pylint 的結果中首先顯示一些”*”字元 , 後面緊跟模組的名字,然後是一系列的 message, message 的格式如下:

MESSAGE_TYPE 有如下幾種:

(C) 慣例。違反了編碼風格標準

(R) 重構。寫得非常糟糕的程式碼。

(W) 警告。某些 Python 特定的問題。

(E) 錯誤。很可能是程式碼中的錯誤。

(F) 致命錯誤。阻止 Pylint 進一步執行的錯誤。

清單 2. Pylint 中的 utils 模組的輸出結果

報告部分:

在原始碼分析結束後面,會有一系列的報告,每個報告關注於專案的某些方面,如每種類別的 message 的數目,模組的依賴關係等等。具體來說,報告中會包含如下的方面:

  • 檢查的 module 的個數。
  • 對於每個 module, 錯誤和警告在其中所佔的百分比。比如有兩個 module A 和 B, 如果一共檢查出來 4 個錯誤,1 個錯誤是在 A 中,3 個錯誤是在 B 中,那麼 A 的錯誤的百分比是 25%, B 的錯誤的百分比是 75%。
  • 錯誤,警告的總數量。

使用 Pylint 分析 Python 程式碼的具體示例

下面是一個從 xml 檔案中讀取一些值並顯示出來的一段 Python 程式碼 dw.py,程式碼如下:

清單 3. 原始碼
清單 4. identity.xml 的內容

這時候使用 Pylint 的結果(這是從 html 格式的輸出中拷貝的)為:

清單 5. Pylint 的分析結果

輸出中第一部分是原始碼分析,第二部分是報告。輸出結果中有這麼多資訊,從哪裡開始分析呢?首先使用如下的步驟來分析程式碼:

1. 因為輸出結果太長,所以可以先不讓它輸出報告部分,先根據原始碼分析部分來找出程式碼中的問題。使用選項 "--reports=n"

2. 使用選項 "--include-ids=y"。可以獲取到原始碼分析部分每條資訊的 ID。

清單 6. 使用 pylint –reports=n –include-ids=y dw.py 的結果

每個資訊前面都會加上一個 id, 如果不理解這個資訊的意思,可以通過 pylint --help-msg=id來檢視。

清單 7. 使用 pylint –help-msg= C0111 的結果

3. 開始分析每個原始碼中的問題。從上面知道,第一個問題的原因是缺少 docstring,在程式碼中增加 docstring, 修改後的程式碼如下:

清單 8. 增加 docstring 修改後的原始碼

重新執行 pylint --reports=n --include-ids=y dw.py,結果為:

清單 9. 執行結果

可以看到原始碼中的第一個問題已被解決。

4. 關於第二個 C0322 的問題,這裡的分析結果說明得比較清楚,是程式碼第七行中的等號運算子兩邊沒有空格。我們在這裡加上空格,重新執行 pylint --reports=n --include-ids=y dw.py,結果為:

清單 10. 執行結果

5. 可以看到現在問題只剩下 C0103 了。這裡的意思是變數命名規則應該符合後面正規表示式的規定。Pylint 定義了一系列針對變數,函式,類等的名字的命名規則。實際中我們不一定要使用這樣的命名規則,我們可以定義使用正規表示式定義自己的命名規則,比如使用選項 --const-rgx='[a-z_][a-z0-9_]{2,30}$',我們將變數 xmlDom改為 xmldom, 程式碼如下:

清單 11. 將變數 xmlDom 改為 xmldom 後的原始碼

執行 pylint --reports=n --include-ids=y --const-rgx='[a-z_][a-z0-9_]{2,30}$' dw.py,結果中就沒有任何問題了。

6. 如果希望一個組裡的人都使用這些統一的規則,來規範一個部門的程式碼風格。比如說大家都使用 --const-rgx='[a-z_][a-z0-9_]{2,30}$'作為命名規則,那麼一個比較便捷的方法是使用配置檔案。

使用 pylint --generate-rcfile > pylint.conf來生成一個示例配置檔案,然後編輯其中的 --const-rgx選項。或者也可以直接 pylint --const-rgx='[a-z_][a-z0-9_]{2,30}$' --generate-rcfile > pylint.conf,這樣生成的配置檔案中 --const-rgx選項直接就是 '[a-z_][a-z0-9_]{2,30}$'了。

以後執行 Pylint 的時候指定配置檔案:pylint --rcfile=pylint.conf dw.py

這樣 Pylint 就會按照配置檔案 pylint.conf中的選項來指定引數。在一個部門中,大家可以共同使用同一個配置檔案,這樣就可以保持一致的程式碼風格。

7. 如果把 report 部分加上,即不使用 --reports=n,可以看到報告部分的內容

結束語

本文通過詳細的理論介紹和簡單易懂的例項全面介紹了 Python 程式碼分析工具 Pylint。相信讀者看完後一定可以輕鬆地將 Pylint 運用到自己的開發工程中。

相關文章