Pylint 是什么


Pylint 是什么

Pylint 是一個 Python 代碼分析工具,它分析 Python 代碼中的錯誤,查找不符合代碼風格標准(Pylint 默認使用的代碼風格是 PEP 8,具體信息,請參閱參考資料)和有潛在問題的代碼。目前 Pylint 的最新版本是 pylint-0.18.1。

  • Pylint 是一個 Python 工具,除了平常代碼分析工具的作用之外,它提供了更多的功能:如檢查一行代碼的長度,變量名是否符合命名標准,一個聲明過的接口是否被真正實現等等。
  • Pylint 的一個很大的好處是它的高可配置性,高可定制性,並且可以很容易寫小插件來添加功能。
  • 如果運行兩次 Pylint,它會同時顯示出當前和上次的運行結果,從而可以看出代碼質量是否得到了改進。
  • 目前在 eclipse 的 pydev 插件中也集成了 Pylint。

    PTVS也集成的杠杠的

  • 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: 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 的內容
       <IBM> 
              <DW> 
                      <linux id="100" name="python" count="3000" /> 
              </DW> 
       </IBM>

      這時候使用 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,可以看到報告部分的內容


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM