python代碼檢查工具pylint 讓你的python更規(guī)范
更新時間:2012年09月05日 17:17:55 作者:
遇到一個新的問題,總是離不開3W原則(What,Why,hoW),下面是對python代碼靜態(tài)檢測工具pylint的學(xué)習(xí)
1、pylint是什么?
Pylint 是一個 Python 代碼分析工具,它分析 Python 代碼中的錯誤,查找不符合代碼風(fēng)格標(biāo)準(zhǔn)(Pylint 默認(rèn)使用的代碼風(fēng)格是 PEP 8,具體信息,請參閱參考資料)和有潛在問題的代碼。目前 Pylint 的最新版本是 pylint-0.18.1。
Pylint 是一個 Python 工具,除了平常代碼分析工具的作用之外,它提供了更多的功能:如檢查一行代碼的長度,變量名是否符合命名標(biāo)準(zhǔn),一個聲明過的接口是否被真正實(shí)現(xiàn)等等。
Pylint 的一個很大的好處是它的高可配置性,高可定制性,并且可以很容易寫小插件來添加功能。
如果運(yùn)行兩次 Pylint,它會同時顯示出當(dāng)前和上次的運(yùn)行結(jié)果,從而可以看出代碼質(zhì)量是否得到了改進(jìn)。
目前在 eclipse 的 pydev 插件中也集成了 Pylint。
pylint是一個Python代碼風(fēng)格的檢查工具, 它依據(jù)的標(biāo)準(zhǔn)是Guido van Rossum的PEP8。
pylint類似于PyChecker, 但提供了更多的功能, 如檢查代碼行的長度, 檢查變量命名是否符合編碼規(guī)范, 或檢查聲明的接口是否被真正的實(shí)現(xiàn), 完整的檢查功能請參見http://www.logilab.org/card/pylintfeatures。
pylint的最大優(yōu)勢在于其高度的可配置化和可定制化,你可以很容易地寫一個小插件添加個人功能。
安裝方法:pip install pylint
參考鏈接:
http://www.ibm.com/developerworks/cn/aix/library/au-cleancode/index.html
http://www.douban.com/note/46830857/
http://zh.wikipedia.org/wiki/Pylint
2、為什么使用pylint?
為了寫出好代碼。什么是好代碼?符合團(tuán)隊(duì)編碼習(xí)慣的代碼:統(tǒng)一的命名,結(jié)構(gòu)。
它的類似產(chǎn)品是什么?PyChecker
你還有啥補(bǔ)充?
3、 怎么使用pylint?
基礎(chǔ)使用:
通過三種代碼來進(jìn)行測時,得分從1,不斷的根據(jù)pylint的提示進(jìn)行重構(gòu),最終得到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)
基本上有以下幾種判斷標(biāo)準(zhǔn):
1、命名方式
2、docstring
當(dāng)然直接用pylint進(jìn)行包檢測也是可以的:pylint package
參看下面了解更多的使用方法,一定要動手練習(xí)才行:
參看內(nèi)容:
Pylint 的調(diào)用
清單 1. Pylint 的調(diào)用命令
pylint [options] module_or_package
使用 Pylint 對一個模塊 module.py 進(jìn)行代碼檢查:
1. 進(jìn)入這個模塊所在的文件夾,運(yùn)行 pylint [options] module.py
這種調(diào)用方式是一直可以工作的,因?yàn)楫?dāng)前的工作目錄會被自動加入 Python 的路徑中。
2. 不進(jìn)入模塊所在的文件夾,運(yùn)行 pylint [options] directory/module.py
這種調(diào)用方式當(dāng)如下條件滿足的時候是可以工作的:directory 是個 Python 包 ( 比如包含一個 __init__.py 文件 ),或者 directory 被加入了 Python 的路徑中。
使用 Pylint 對一個包 pakage 進(jìn)行代碼檢查:
1. 進(jìn)入這個包所在文件夾,運(yùn)行 pylint [options] pakage。
這種調(diào)用方式是一直可以工作的,因?yàn)楫?dāng)前的工作目錄會被自動加入 Python 的路徑中。
2. 不進(jìn)入包所在的文件夾,運(yùn)行 pylint [options] directory/ pakage。
這種情況下當(dāng)如下條件滿足的時候是可以工作的:directory 被加入了 Python 的路徑中。比如在 Linux 上,export PYTHONPATH=$PYTHONPATH: directory。
此外,對于安裝了 tkinter 包的機(jī)器,可以使用命令 pylint-gui打開一個簡單的 GUI 界面,在這里輸入模塊或者包的名字 ( 規(guī)則同命令行 ), 點(diǎn)擊 Run,Pylint 的輸出會在 GUI 中顯示。
Pylint 的常用命令行參數(shù)
-h,–help
顯示所有幫助信息。
–generate-rcfile
可以使用 pylint –generate-rcfile 來生成一個配置文件示例。可以使用重定向把這個配置文件保存下來用做以后使用。也可以在前面加上其它選項(xiàng),使這些選項(xiàng)的值被包含在這個產(chǎn)生的配置文件里。如:pylint –persistent=n –generate-rcfile > pylint.conf,查看 pylint.conf,可以看到 persistent=no,而不再是其默認(rèn)值 yes。
–rcfile=
指定一個配置文件。把使用的配置放在配置文件中,這樣不僅規(guī)范了自己代碼,也可以方便地和別人共享這些規(guī)范。
-i , –include-ids=
在輸出中包含 message 的 id, 然后通過 pylint –help-msg=來查看這個錯誤的詳細(xì)信息,這樣可以具體地定位錯誤。
-r , –reports=
默認(rèn)是 y, 表示 Pylint 的輸出中除了包含源代碼分析部分,也包含報告部分。
–files-output=
將每個 module /package 的 message 輸出到一個以 pylint_module/package. [txt|html] 命名的文件中,如果有 report 的話,輸出到名為 pylint_global.[txt|html] 的文件中。默認(rèn)是輸出到屏幕上不輸出到文件里。
-f , –output-format=
設(shè)置輸出格式??梢赃x擇的格式有 text, parseable, colorized, msvs (visual studio) 和 html, 默認(rèn)的輸出格式是 text。
–disable-msg=
禁止指定 id 的 message. 比如說輸出中包含了 W0402 這個 warning 的 message, 如果不希望它在輸出中出現(xiàn),可以使用 –disable-msg= W0402
Pylint 的輸出
Pylint的默認(rèn)輸出格式是原始文本(raw text)格式 ,可以通過 -f ,–output-format= 來指定別的輸出格式如html等等。在Pylint的輸出中有如下兩個部分:源代碼分析部分和報告部分。
源代碼分析部分:
對于每一個 Python 模塊,Pylint 的結(jié)果中首先顯示一些”*”字符 , 后面緊跟模塊的名字,然后是一系列的 message, message 的格式如下:
MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE
MESSAGE_TYPE 有如下幾種:
(C) 慣例。違反了編碼風(fēng)格標(biāo)準(zhǔn)
(R) 重構(gòu)。寫得非常糟糕的代碼。
(W) 警告。某些 Python 特定的問題。
(E) 錯誤。很可能是代碼中的錯誤。
(F) 致命錯誤。阻止 Pylint 進(jìn)一步運(yùn)行的錯誤。
清單 2. Pylint 中的 utils 模塊的輸出結(jié)果
************* 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)
報告部分:
在源代碼分析結(jié)束后面,會有一系列的報告,每個報告關(guān)注于項(xiàng)目的某些方面,如每種類別的 message 的數(shù)目,模塊的依賴關(guān)系等等。具體來說,報告中會包含如下的方面:
檢查的 module 的個數(shù)。
對于每個 module, 錯誤和警告在其中所占的百分比。比如有兩個 module A 和 B, 如果一共檢查出來 4 個錯誤,1 個錯誤是在 A 中,3 個錯誤是在 B 中,那么 A 的錯誤的百分比是 25%, B 的錯誤的百分比是 75%。
錯誤,警告的總數(shù)量。
回頁首
使用 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 的內(nèi)容
這時候使用 Pylint 的結(jié)果(這是從 html 格式的輸出中拷貝的)為:
清單 5. Pylint 的分析結(jié)果
************* 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 部分省略
輸出中第一部分是源代碼分析,第二部分是報告。輸出結(jié)果中有這么多信息,從哪里開始分析呢?首先使用如下的步驟來分析代碼:
1. 因?yàn)檩敵鼋Y(jié)果太長,所以可以先不讓它輸出報告部分,先根據(jù)源代碼分析部分來找出代碼中的問題。使用選項(xiàng) “–reports=n”。
2. 使用選項(xiàng) “–include-ids=y”??梢垣@取到源代碼分析部分每條信息的 ID。
清單 6. 使用 pylint –reports=n –include-ids=y dw.py 的結(jié)果
************* 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 的結(jié)果
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')
重新運(yùn)行 pylint –reports=n –include-ids=y dw.py,結(jié)果為:
清單 9. 運(yùn)行結(jié)果
************* 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. 關(guān)于第二個 C0322 的問題,這里的分析結(jié)果說明得比較清楚,是代碼第七行中的等號運(yùn)算符兩邊沒有空格。我們在這里加上空格,重新運(yùn)行 pylint –reports=n –include-ids=y dw.py,結(jié)果為:
清單 10. 運(yùn)行結(jié)果
************* 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. 可以看到現(xiàn)在問題只剩下 C0103 了。這里的意思是變量命名規(guī)則應(yīng)該符合后面正則表達(dá)式的規(guī)定。Pylint 定義了一系列針對變量,函數(shù),類等的名字的命名規(guī)則。實(shí)際中我們不一定要使用這樣的命名規(guī)則,我們可以定義使用正則表達(dá)式定義自己的命名規(guī)則,比如使用選項(xiàng) –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')
運(yùn)行 pylint –reports=n –include-ids=y –const-rgx='[a-z_][a-z0-9_]{2,30}$' dw.py,結(jié)果中就沒有任何問題了。
6. 如果希望一個組里的人都使用這些統(tǒng)一的規(guī)則,來規(guī)范一個部門的代碼風(fēng)格。比如說大家都使用 –const-rgx='[a-z_][a-z0-9_]{2,30}$'作為命名規(guī)則,那么一個比較便捷的方法是使用配置文件。
使用 pylint –generate-rcfile > pylint.conf來生成一個示例配置文件,然后編輯其中的 –const-rgx選項(xiàng)?;蛘咭部梢灾苯?pylint –const-rgx='[a-z_][a-z0-9_]{2,30}$' –generate-rcfile > pylint.conf,這樣生成的配置文件中 –const-rgx選項(xiàng)直接就是 ‘[a-z_][a-z0-9_]{2,30}$'了。
以后運(yùn)行 Pylint 的時候指定配置文件:pylint –rcfile=pylint.conf dw.py
這樣 Pylint 就會按照配置文件 pylint.conf中的選項(xiàng)來指定參數(shù)。在一個部門中,大家可以共同使用同一個配置文件,這樣就可以保持一致的代碼風(fēng)格。
7. 如果把 report 部分加上,即不使用 –reports=n,可以看到報告部分的內(nèi)容。
與此相關(guān):
代碼審察工具:
http://www.cnblogs.com/LiGleam/archive/2012/02/19/2358549.html
http://www.ibm.com/developerworks/cn/linux/l-cn-pylint/index.html?ca=drs-cn-1217
Pylint 是一個 Python 代碼分析工具,它分析 Python 代碼中的錯誤,查找不符合代碼風(fēng)格標(biāo)準(zhǔn)(Pylint 默認(rèn)使用的代碼風(fēng)格是 PEP 8,具體信息,請參閱參考資料)和有潛在問題的代碼。目前 Pylint 的最新版本是 pylint-0.18.1。
Pylint 是一個 Python 工具,除了平常代碼分析工具的作用之外,它提供了更多的功能:如檢查一行代碼的長度,變量名是否符合命名標(biāo)準(zhǔn),一個聲明過的接口是否被真正實(shí)現(xiàn)等等。
Pylint 的一個很大的好處是它的高可配置性,高可定制性,并且可以很容易寫小插件來添加功能。
如果運(yùn)行兩次 Pylint,它會同時顯示出當(dāng)前和上次的運(yùn)行結(jié)果,從而可以看出代碼質(zhì)量是否得到了改進(jìn)。
目前在 eclipse 的 pydev 插件中也集成了 Pylint。
pylint是一個Python代碼風(fēng)格的檢查工具, 它依據(jù)的標(biāo)準(zhǔn)是Guido van Rossum的PEP8。
pylint類似于PyChecker, 但提供了更多的功能, 如檢查代碼行的長度, 檢查變量命名是否符合編碼規(guī)范, 或檢查聲明的接口是否被真正的實(shí)現(xiàn), 完整的檢查功能請參見http://www.logilab.org/card/pylintfeatures。
pylint的最大優(yōu)勢在于其高度的可配置化和可定制化,你可以很容易地寫一個小插件添加個人功能。
安裝方法:pip install pylint
參考鏈接:
http://www.ibm.com/developerworks/cn/aix/library/au-cleancode/index.html
http://www.douban.com/note/46830857/
http://zh.wikipedia.org/wiki/Pylint
2、為什么使用pylint?
為了寫出好代碼。什么是好代碼?符合團(tuán)隊(duì)編碼習(xí)慣的代碼:統(tǒng)一的命名,結(jié)構(gòu)。
它的類似產(chǎn)品是什么?PyChecker
你還有啥補(bǔ)充?
3、 怎么使用pylint?
基礎(chǔ)使用:
通過三種代碼來進(jìn)行測時,得分從1,不斷的根據(jù)pylint的提示進(jìn)行重構(gòu),最終得到10分。
v1_fetch.py:
復(fù)制代碼 代碼如下:
#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:
復(fù)制代碼 代碼如下:
#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:
復(fù)制代碼 代碼如下:
#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)
基本上有以下幾種判斷標(biāo)準(zhǔn):
1、命名方式
2、docstring
當(dāng)然直接用pylint進(jìn)行包檢測也是可以的:pylint package
參看下面了解更多的使用方法,一定要動手練習(xí)才行:
參看內(nèi)容:
Pylint 的調(diào)用
清單 1. Pylint 的調(diào)用命令
pylint [options] module_or_package
使用 Pylint 對一個模塊 module.py 進(jìn)行代碼檢查:
1. 進(jìn)入這個模塊所在的文件夾,運(yùn)行 pylint [options] module.py
這種調(diào)用方式是一直可以工作的,因?yàn)楫?dāng)前的工作目錄會被自動加入 Python 的路徑中。
2. 不進(jìn)入模塊所在的文件夾,運(yùn)行 pylint [options] directory/module.py
這種調(diào)用方式當(dāng)如下條件滿足的時候是可以工作的:directory 是個 Python 包 ( 比如包含一個 __init__.py 文件 ),或者 directory 被加入了 Python 的路徑中。
使用 Pylint 對一個包 pakage 進(jìn)行代碼檢查:
1. 進(jìn)入這個包所在文件夾,運(yùn)行 pylint [options] pakage。
這種調(diào)用方式是一直可以工作的,因?yàn)楫?dāng)前的工作目錄會被自動加入 Python 的路徑中。
2. 不進(jìn)入包所在的文件夾,運(yùn)行 pylint [options] directory/ pakage。
這種情況下當(dāng)如下條件滿足的時候是可以工作的:directory 被加入了 Python 的路徑中。比如在 Linux 上,export PYTHONPATH=$PYTHONPATH: directory。
此外,對于安裝了 tkinter 包的機(jī)器,可以使用命令 pylint-gui打開一個簡單的 GUI 界面,在這里輸入模塊或者包的名字 ( 規(guī)則同命令行 ), 點(diǎn)擊 Run,Pylint 的輸出會在 GUI 中顯示。
Pylint 的常用命令行參數(shù)
-h,–help
顯示所有幫助信息。
–generate-rcfile
可以使用 pylint –generate-rcfile 來生成一個配置文件示例。可以使用重定向把這個配置文件保存下來用做以后使用。也可以在前面加上其它選項(xiàng),使這些選項(xiàng)的值被包含在這個產(chǎn)生的配置文件里。如:pylint –persistent=n –generate-rcfile > pylint.conf,查看 pylint.conf,可以看到 persistent=no,而不再是其默認(rèn)值 yes。
–rcfile=
指定一個配置文件。把使用的配置放在配置文件中,這樣不僅規(guī)范了自己代碼,也可以方便地和別人共享這些規(guī)范。
-i , –include-ids=
在輸出中包含 message 的 id, 然后通過 pylint –help-msg=來查看這個錯誤的詳細(xì)信息,這樣可以具體地定位錯誤。
-r , –reports=
默認(rèn)是 y, 表示 Pylint 的輸出中除了包含源代碼分析部分,也包含報告部分。
–files-output=
將每個 module /package 的 message 輸出到一個以 pylint_module/package. [txt|html] 命名的文件中,如果有 report 的話,輸出到名為 pylint_global.[txt|html] 的文件中。默認(rèn)是輸出到屏幕上不輸出到文件里。
-f , –output-format=
設(shè)置輸出格式??梢赃x擇的格式有 text, parseable, colorized, msvs (visual studio) 和 html, 默認(rèn)的輸出格式是 text。
–disable-msg=
禁止指定 id 的 message. 比如說輸出中包含了 W0402 這個 warning 的 message, 如果不希望它在輸出中出現(xiàn),可以使用 –disable-msg= W0402
Pylint 的輸出
Pylint的默認(rèn)輸出格式是原始文本(raw text)格式 ,可以通過 -f ,–output-format= 來指定別的輸出格式如html等等。在Pylint的輸出中有如下兩個部分:源代碼分析部分和報告部分。
源代碼分析部分:
對于每一個 Python 模塊,Pylint 的結(jié)果中首先顯示一些”*”字符 , 后面緊跟模塊的名字,然后是一系列的 message, message 的格式如下:
MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE
MESSAGE_TYPE 有如下幾種:
(C) 慣例。違反了編碼風(fēng)格標(biāo)準(zhǔn)
(R) 重構(gòu)。寫得非常糟糕的代碼。
(W) 警告。某些 Python 特定的問題。
(E) 錯誤。很可能是代碼中的錯誤。
(F) 致命錯誤。阻止 Pylint 進(jìn)一步運(yùn)行的錯誤。
清單 2. Pylint 中的 utils 模塊的輸出結(jié)果
************* 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)
報告部分:
在源代碼分析結(jié)束后面,會有一系列的報告,每個報告關(guān)注于項(xiàng)目的某些方面,如每種類別的 message 的數(shù)目,模塊的依賴關(guān)系等等。具體來說,報告中會包含如下的方面:
檢查的 module 的個數(shù)。
對于每個 module, 錯誤和警告在其中所占的百分比。比如有兩個 module A 和 B, 如果一共檢查出來 4 個錯誤,1 個錯誤是在 A 中,3 個錯誤是在 B 中,那么 A 的錯誤的百分比是 25%, B 的錯誤的百分比是 75%。
錯誤,警告的總數(shù)量。
回頁首
使用 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 的內(nèi)容
這時候使用 Pylint 的結(jié)果(這是從 html 格式的輸出中拷貝的)為:
清單 5. Pylint 的分析結(jié)果
************* 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 部分省略
輸出中第一部分是源代碼分析,第二部分是報告。輸出結(jié)果中有這么多信息,從哪里開始分析呢?首先使用如下的步驟來分析代碼:
1. 因?yàn)檩敵鼋Y(jié)果太長,所以可以先不讓它輸出報告部分,先根據(jù)源代碼分析部分來找出代碼中的問題。使用選項(xiàng) “–reports=n”。
2. 使用選項(xiàng) “–include-ids=y”??梢垣@取到源代碼分析部分每條信息的 ID。
清單 6. 使用 pylint –reports=n –include-ids=y dw.py 的結(jié)果
************* 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 的結(jié)果
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')
重新運(yùn)行 pylint –reports=n –include-ids=y dw.py,結(jié)果為:
清單 9. 運(yùn)行結(jié)果
************* 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. 關(guān)于第二個 C0322 的問題,這里的分析結(jié)果說明得比較清楚,是代碼第七行中的等號運(yùn)算符兩邊沒有空格。我們在這里加上空格,重新運(yùn)行 pylint –reports=n –include-ids=y dw.py,結(jié)果為:
清單 10. 運(yùn)行結(jié)果
************* 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. 可以看到現(xiàn)在問題只剩下 C0103 了。這里的意思是變量命名規(guī)則應(yīng)該符合后面正則表達(dá)式的規(guī)定。Pylint 定義了一系列針對變量,函數(shù),類等的名字的命名規(guī)則。實(shí)際中我們不一定要使用這樣的命名規(guī)則,我們可以定義使用正則表達(dá)式定義自己的命名規(guī)則,比如使用選項(xiàng) –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')
運(yùn)行 pylint –reports=n –include-ids=y –const-rgx='[a-z_][a-z0-9_]{2,30}$' dw.py,結(jié)果中就沒有任何問題了。
6. 如果希望一個組里的人都使用這些統(tǒng)一的規(guī)則,來規(guī)范一個部門的代碼風(fēng)格。比如說大家都使用 –const-rgx='[a-z_][a-z0-9_]{2,30}$'作為命名規(guī)則,那么一個比較便捷的方法是使用配置文件。
使用 pylint –generate-rcfile > pylint.conf來生成一個示例配置文件,然后編輯其中的 –const-rgx選項(xiàng)?;蛘咭部梢灾苯?pylint –const-rgx='[a-z_][a-z0-9_]{2,30}$' –generate-rcfile > pylint.conf,這樣生成的配置文件中 –const-rgx選項(xiàng)直接就是 ‘[a-z_][a-z0-9_]{2,30}$'了。
以后運(yùn)行 Pylint 的時候指定配置文件:pylint –rcfile=pylint.conf dw.py
這樣 Pylint 就會按照配置文件 pylint.conf中的選項(xiàng)來指定參數(shù)。在一個部門中,大家可以共同使用同一個配置文件,這樣就可以保持一致的代碼風(fēng)格。
7. 如果把 report 部分加上,即不使用 –reports=n,可以看到報告部分的內(nèi)容。
與此相關(guān):
代碼審察工具:
http://www.cnblogs.com/LiGleam/archive/2012/02/19/2358549.html
http://www.ibm.com/developerworks/cn/linux/l-cn-pylint/index.html?ca=drs-cn-1217
相關(guān)文章
Python機(jī)器學(xué)習(xí)入門(三)之Python數(shù)據(jù)準(zhǔn)備
這篇文章主要介紹了Python機(jī)器學(xué)習(xí)入門知識,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-08-08python3使用騰訊企業(yè)郵箱發(fā)送郵件的實(shí)例
今天小編就為大家分享一篇python3使用騰訊企業(yè)郵箱發(fā)送郵件的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-06-06python 多進(jìn)程共享全局變量之Manager()詳解
這篇文章主要介紹了python 多進(jìn)程共享全局變量之Manager()詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-08-08Python基于BeautifulSoup和requests實(shí)現(xiàn)的爬蟲功能示例
這篇文章主要介紹了Python基于BeautifulSoup和requests實(shí)現(xiàn)的爬蟲功能,結(jié)合實(shí)例形式分析了Python使用BeautifulSoup和requests庫爬取網(wǎng)站指定信息的相關(guān)操作技巧,需要的朋友可以參考下2019-08-08python3 pygame實(shí)現(xiàn)接小球游戲
這篇文章主要為大家詳細(xì)介紹了python3 pygame實(shí)現(xiàn)接小球游戲,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-05-05Pytest?fixture及conftest相關(guān)詳解
這篇文章主要介紹了Pytest?fixture及conftest相關(guān)詳解,fixture是在測試函數(shù)運(yùn)行前后,由pytest執(zhí)行的外殼函數(shù),更多相關(guān)內(nèi)容需要的朋友可以參考一下2022-09-09