一、pylint是什麼?html
Pylint 是一個 Python 代碼分析工具,它分析 Python 代碼中的錯誤,查找不符合代碼風格標準(Pylint 默認使用的代碼風格是 PEP 8,具體信息,請參閱參考資料)和有潛在問題的代碼。目前 Pylint 的最新版本是 pylint-0.18.1。python
Pylint 是一個 Python 工具,除了日常代碼分析工具的做用以外,它提供了更多的功能:如檢查一行代碼的長度,變量名是否符合命名標準,一個聲明過的接口是否被真正實現等等。linux
Pylint 的一個很大的好處是它的高可配置性,高可定製性,而且能夠很容易寫小插件來添加功能。正則表達式
若是運行兩次 Pylint,它會同時顯示出當前和上次的運行結果,從而能夠看出代碼質量是否獲得了改進。dom
目前在 eclipse 的 pydev 插件中也集成了 Pylint。eclipse
pylint是一個Python代碼風格的檢查工具, 它依據的標準是Guido van Rossum的PEP8。ide
pylint相似於PyChecker, 但提供了更多的功能, 如檢查代碼行的長度, 檢查變量命名是否符合編碼規範, 或檢查聲明的接口是否被真正的實現, 完整的檢查功能請參見http://www.logilab.org/card/pylintfeatures。函數
pylint的最大優點在於其高度的可配置化和可定製化,你能夠很容易地寫一個小插件添加我的功能。工具
安裝方法:pip install pylintfetch
二、爲何使用pylint?
爲了寫出好代碼。什麼是好代碼?符合團隊編碼習慣的代碼:統一的命名,結構。
它的相似產品是什麼?PyChecker
你還有啥補充?
三、 怎麼使用pylint?
基礎使用:
經過三種代碼來進行測時,得分從1,不斷的根據pylint的提示進行重構,最終獲得10分。
v1_fetch.py:
#coding:utf-8 import urllib import time def a(url): content = urllib.urlopen(url).read() f = open('tmp%s.html' % str(time.time()), 'w') f.write(content) f.close() def main(urls): for url in urls: a(url) if __name__ == '__main__': urls = ['http://www.baidu.com','http://www.sohu.com'] main(urls) |
修改命名:
v2_fetch.py:
#coding:utf-8 import urllib import time def fetch(url): content = urllib.urlopen(url).read() f_html = open('tmp%s.html' % str(time.time()), 'w') f_html.write(content) f_html.close() def main(urls): for url in urls: fetch(url) if __name__ == '__main__': from_urls = ['http://www.baidu.com','http://www.sohu.com'] main(from_urls) |
再次修改:
v3_fetch.py:
#coding:utf-8 ''' a test function module ''' import urllib import time def fetch(url): ''' fetch url ''' content = urllib.urlopen(url).read() f_html = open('tmp%s.html' % str(time.time()), 'w') f_html.write(content) f_html.close() def main(urls): ''' main func to be called ''' for url in urls: fetch(url) if __name__ == '__main__': FROM_URLS = ['http://www.baidu.com','http://www.sohu.com'] main(FROM_URLS) |
基本上有如下幾種判斷標準:
一、命名方式
二、docstring
固然直接用pylint進行包檢測也是能夠的:pylint package
參看下面瞭解更多的使用方法,必定要動手練習才行:
參看內容:
Pylint 的調用
清單 1. Pylint 的調用命令
pylint [options] module_or_package
使用 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=
指定一個配置文件。把使用的配置放在配置文件中,這樣不只規範了本身代碼,也能夠方便地和別人共享這些規範。
-i , –include-ids=
在輸出中包含 message 的 id, 而後經過 pylint –help-msg=來查看這個錯誤的詳細信息,這樣能夠具體地定位錯誤。
-r , –reports=
默認是 y, 表示 Pylint 的輸出中除了包含源代碼分析部分,也包含報告部分。
–files-output=
將每一個 module /package 的 message 輸出到一個以 pylint_module/package. [txt|html] 命名的文件中,若是有 report 的話,輸出到名爲 pylint_global.[txt|html] 的文件中。默認是輸出到屏幕上不輸出到文件裏。
-f , –output-format=
設置輸出格式。能夠選擇的格式有 text, parseable, colorized, msvs (visual studio) 和 html, 默認的輸出格式是 text。
–disable-msg=
禁止指定 id 的 message. 好比說輸出中包含了 W0402 這個 warning 的 message, 若是不但願它在輸出中出現,可使用 –disable-msg= W0402
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 進一步運行的錯誤。
清單 2. Pylint 中的 utils 模塊的輸出結果
************* Module utils
C: 88:Message: Missing docstring
R: 88:Message: Too few public methods (0/2)
C:183:MessagesHandlerMixIn._cat_ids: Missing docstring
R:183:MessagesHandlerMixIn._cat_ids: Method could be a function
R:282:MessagesHandlerMixIn.list_messages: Too many branches (14/12)
報告部分:
在源代碼分析結束後面,會有一系列的報告,每一個報告關注於項目的某些方面,如每種類別的 message 的數目,模塊的依賴關係等等。具體來講,報告中會包含以下的方面:
檢查的 module 的個數。
對於每一個 module, 錯誤和警告在其中所佔的百分比。好比有兩個 module A 和 B, 若是一共檢查出來 4 個錯誤,1 個錯誤是在 A 中,3 個錯誤是在 B 中,那麼 A 的錯誤的百分比是 25%, B 的錯誤的百分比是 75%。
錯誤,警告的總數量。
回頁首
使用 Pylint 分析 Python 代碼的具體示例
下面是一個從 xml 文件中讀取一些值並顯示出來的一段 Python 代碼 dw.py,代碼以下:
清單 3. 源碼
import string
#!/usr/bin/env python
import xml.dom.minidom
xmlDom=xml.dom.minidom.parse(「identity.xml」)
organizations = xmlDom.getElementsByTagName(‘DW')
for org in organizations:
products = org.getElementsByTagName(‘linux')
for product in products:
print ‘ID: ‘ + product.getAttribute(‘id')
print ‘Name: ‘ + product.getAttribute(‘name')
print ‘Word Count: ‘ + product.getAttribute(‘count')
清單 4. identity.xml 的內容
這時候使用 Pylint 的結果(這是從 html 格式的輸出中拷貝的)爲:
清單 5. Pylint 的分析結果
************* Module dw
C:1:Missing docstring
C:5:Operator not preceded by a space xmlDom=xml.dom.minidom.parse(「identity.xml」) ^
C:5:Invalid name 「xmlDom」 (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C:6:Invalid name 「organizations」 (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
Report 部分省略
輸出中第一部分是源代碼分析,第二部分是報告。輸出結果中有這麼多信息,從哪裏開始分析呢?首先使用以下的步驟來分析代碼:
1. 由於輸出結果太長,因此能夠先不讓它輸出報告部分,先根據源代碼分析部分來找出代碼中的問題。使用選項 「–reports=n」。
2. 使用選項 「–include-ids=y」。能夠獲取到源代碼分析部分每條信息的 ID。
清單 6. 使用 pylint –reports=n –include-ids=y dw.py 的結果
************* Module dw
C0111: 1: Missing docstring
C0322: 5: Operator not preceded by a space xmlDom=xml.dom.minidom.parse(「identity.xml」) ^
C0103: 5: Invalid name 「xmlDom」 (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C0103: 6: Invalid name 「organizations」 (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
每一個信息前面都會加上一個 id, 若是不理解這個信息的意思,能夠經過 pylint –help-msg=id來查看。
清單 7. 使用 pylint –help-msg= C0111 的結果
C0111: *Missing docstring*
Used when a module, function, class or method has no docstring. Some special
methods like __init__ doesn't necessary require a docstring.
This message belongs to the basic checker.
3. 開始分析每一個源代碼中的問題。從上面知道,第一個問題的緣由是缺乏 docstring,在代碼中增長 docstring, 修改後的代碼以下:
清單 8. 增長 docstring 修改後的源碼
#!/usr/bin/env python
「」"This script parse the content of a xml file」"」
import xml.dom.minidom
xmlDom=xml.dom.minidom.parse(「identity.xml」)
organizations = xmlDom.getElementsByTagName(‘DW')
for org in organizations:
products = org.getElementsByTagName(‘linux')
for product in products:
print ‘ID: ‘ + product.getAttribute(‘id')
print ‘Name: ‘ + product.getAttribute(‘name')
print ‘Word Count: ‘ + product.getAttribute(‘count')
從新運行 pylint –reports=n –include-ids=y dw.py,結果爲:
清單 9. 運行結果
************* Module dw
C0322: 7: Operator not preceded by a space
xmlDom=xml.dom.minidom.parse(「identity.xml」)
^
C0103: 7: Invalid name 「xmlDom」 (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C0103: 8: Invalid name 「organizations」 (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
能夠看到源代碼中的第一個問題已被解決。
4. 關於第二個 C0322 的問題,這裏的分析結果說明得比較清楚,是代碼第七行中的等號運算符兩邊沒有空格。咱們在這裏加上空格,從新運行 pylint –reports=n –include-ids=y dw.py,結果爲:
清單 10. 運行結果
************* Module dw
C0103: 7: Invalid name 「xmlDom」 (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C0103: 8: Invalid name 「organizations」 (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
5. 能夠看到如今問題只剩下 C0103 了。這裏的意思是變量命名規則應該符合後面正則表達式的規定。Pylint 定義了一系列針對變量,函數,類等的名字的命名規則。實際中咱們不必定要使用這樣的命名規則,咱們能夠定義使用正則表達式定義本身的命名規則,好比使用選項 –const-rgx='[a-z_][a-z0-9_]{2,30}$',咱們將變量 xmlDom改成 xmldom, 代碼以下:
清單 11. 將變量 xmlDom 改成 xmldom 後的源碼
#!/usr/bin/env python
「」"This script parse the content of a xml file」"」
import xml.dom.minidom
xmldom = xml.dom.minidom.parse(「identity.xml」)
organizations = xmldom.getElementsByTagName(‘DW')
for org in organizations:
products = org.getElementsByTagName(‘linux')
for product in products:
print ‘ID: ‘ + product.getAttribute(‘id')
print ‘Name: ‘ + product.getAttribute(‘name')
print ‘Word Count: ‘ + product.getAttribute(‘count')
運行 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,能夠看到報告部分的內容。
原文來自:http://www.uml.org.cn/codeNorms/201903143.asp
寫的不錯哦