3大利器推薦,幫你寫出規範漂亮的Python程式碼
Python學了好久,但是拿出來review的程式碼好像總是長的不夠俊美,不夠工整!因此標準化的程式碼規範就顯得尤為重要。今天就來推薦3個利器,python界廣泛認同的程式碼風格規範PEP8和兩個超牛的工具pylint和black,分別用於程式碼風格規範檢測和自動優化。
1、程式碼風格規範PEP8
首先講一講為什麼要使用PEP8,我們先來看下面這段程式碼,在相關函式定義後,它是可以正常編譯執行的,但是這段程式碼的怪異風格無論是讓別人閱讀還是自己閱讀都會感到很難受。這就需要一種普遍認同的程式碼風格規範,對行長度、縮排、多行表示式、變數命名約定等內容進行統一,這就是PEP8的意義所在。

需要說明的是,PEP 8中有一些規範是為了方便閱讀,而有一些規範實實在在地影響著程式碼的效能、容錯率或者重構難度。

比如上面這段程式碼,foo函式僅在滿足條件的情況下有返回值、bar函式僅在不滿足條件的情況下有返回值,這樣的程式碼相容性會比較差,正確的做法是保持程式碼一致性,函式中的返回語句都應該返回一個表示式,或者都不返回:

關於PEP8就簡單介紹到這裡,有興趣的朋友可以自行查閱文件。當我們開啟文件的時候會發現PEPE 8規範的內容非常多、非常細。
作為一名新手如果要一條條解讀、一條條記住這些規定實在不是件容易的事情。然而養成良好的程式碼編寫習慣對新手來說又是十分重要的。
下面我們就正式進入主題,介紹兩個簡單又實用的程式碼自動化檢測和優化工具,可以幫助我們快速規範自己的程式碼風格。
2、自動檢測工具Pylint
Pylint 是一個檢查違反 PEP8 規範和常見錯誤的庫,它會自動查詢不符合程式碼風格標準和有潛在問題的程式碼,並在控制檯輸出程式碼中違反規範和出現問題的相關資訊。
1).安裝與使用
與python的其他庫一樣,直接 pip install pylint 即可完成安裝,另外anaconda自帶pylint,所以如果安裝過anaconda不必再單獨安裝此庫。
pylint的使用也非常簡單,最基本的用法直接在控制檯輸入 pylint 路徑/模組名 即可對相關模組的程式碼風格規範 進行檢查,檢查結果會在控制檯輸出。
建議結合 pylint --help 的提示進行學習和檢索。介紹完pylint的基本情況,我們來結合一個例項進行詳細說明。
2).例項演示說明
這裡我找了自己剛學python時寫的一段程式碼進行測試:
import pandas as pd data = [] char_replace_dict = {':':' ', '(':'(', ')':')', ',':','} with open('xmq_survey.txt', 'r', encoding = 'utf-8') as file: for line in file.readlines(): for key, value in char_replace_dict.items(): line = line.replace( key, value)#原來這個是深度引用 #這條程式碼比自己寫的簡介的多,也更python data.append(line) with open('survey.txt', 'w', encoding = 'utf-8') as file: for line in data: file.write(line) raw_data = pd.read_table('survey.txt', delimiter = ' ', header = None) #檢視read_table函式的用法 raw_data.columns = ['Name', 'Raw Info'] raw_data.count() print('successful')
乍一看好像沒什麼大問題,但是經過pylint檢查後卻給出了一堆問題提示(下圖),我們來看檢查結果,每行以大寫字母+冒號開頭的資訊都是一處反饋提示。

其中開頭的大寫字母表示錯誤型別(主要有CRWEF幾類);以逗號間隔的兩個數字表示發現問題的位置(行和列);其後是對問題的具體描述,括號裡的內容稱為message id,可以簡單理解為錯誤型別的詳細分類,通過
pylint --help-msg=
C——違反程式碼風格標準;
R——程式碼結構較差;
W——關於細節的警告;
E——程式碼中存在錯誤;
F——導致Pylint無法繼續執行的錯誤。
例如,我們執行 pylint --help-msg=trailing-newlines 指令,會在控制檯輸出對 trailing-newlines 這種問題的詳細描述:

pylint輸出的最後一行是其對本次檢測的評分,滿分為10分,可以看到我的程式碼本次評分為0分T_T。
既然知道了自己的程式碼哪裡不規範,就去針對性地改正吧,根據提示結果首先將函式引數賦值 = 兩邊的空格去掉,再將多餘的空行去掉,然後執行一下pylint再次進行檢測,得到如下結果:

可以看到,剛才修改過的程式碼相關問題提示已經沒有了,評分也從0分提高到了3.33分。但是仍然有很多問題,這裡就要注意了,PEP8並不是要百分百遵守的,當遵循PEP 8規範會使程式碼可讀性變差、會跟周圍程式碼風格不一致的時候,還是要遵循自己的判斷。
這種情況下,pylint也提供了一種操作,可以手動遮蔽某些問題提示,以剛才的程式碼為例,剩下的幾個問題主要是因為使用了Tab鍵、變數命名不規範、缺少文件說明造成的,我們可以使用
pylint --disable=mixex-indentation,invalid-name,missing-docstring 模組名稱 命令對相關規範進行遮蔽重新檢測,發現問題提示全部消除,評分也提升到了10分。
一段20行的程式碼就檢測到如此之多的問題提示,雖然手動修改程式碼有助於對PEP 8規範的學習,但當專案檔案比較多、指令碼程式碼很長的時候,實在是一個不小的工作量,因此就出現了能夠自動優化程式碼風格的工具。
3、自動優化工具Black
在眾多程式碼格式化工具中,Black算是比較新的一個,它最大的特點是可配置項比較少,個人認為這對於新手來說是件好事,因為我們不必過多考慮如何設定Black,讓 Black 自己做決定就好。
1).安裝與使用
與pylint類似,直接pip install black即可完成該模組的安裝,不過black依賴於Python 3.6+,但它仍然可以格式化Python2的程式碼。
在使用方面black預設讀取指定python檔案並對其進行程式碼規範格式化,然後輸出到原檔案。
l = [1, 2, 3, ]
例如,我們將上面這段程式碼儲存為test.py,然後在控制檯執行 black test.py 指令,再次開啟test.py,發現其中的程式碼變成了這個樣子:
l = [1, 2, 3]
當然,Black的封裝程度再高也是有自定義配置項的,例如使用--version檢視版本、使用--help檢視幫助資訊、使用--diff將修改資訊輸出到控制檯而不更改原檔案,下面我們還是結合一個例項來進行演示說明。
2).例項演示說明
這裡我們仍然使用pylint部分的程式碼進行演示。通過上面的操作我們知道,對這段程式碼直接使用pylint進行測試會輸出很多問題提示,並給出一個評分0。現在我們首先使用black對其進行格式化,得到以下程式碼:
# -*- coding:utf-8 -*- import pandas as pd data = [] char_replace_dict = {':':' ', '(':'(', ')':')', ',':','} with open('xmq_survey.txt', 'r', encoding = 'utf-8') as file: for line in file.readlines(): for key, value in char_replace_dict.items(): line = line.replace( key, value)#原來這個是深度引用 #這條程式碼比自己寫的簡介的多,也更python data.append(line) with open('survey.txt', 'w', encoding = 'utf-8') as file: for line in data: file.write(line) raw_data = pd.read_table('survey.txt', delimiter = ' ', header = None) #檢視read_table函式的用法 raw_data.columns = ['Name', 'Raw Info'] raw_data.count() print('successful')
可能看起來修改前後的程式碼差異並不十分明顯,實質上black已經對程式碼中引數賦值 = 兩端的空格、註釋的格式、製表符等進行了替換和修改,我們使用pylint來進行驗證,執行 pylint 模組名稱 命令,得到如下結果:

可以看到,相對於最初的檔案,評分從0分提高到7.3分,輸出的問題提示少了很多,剩餘的問題主要是缺少說明文件、變數命名不規範.black對於提高我們程式碼規範性價比也是非常高的。
如果不想black直接對原檔案進行修改,而是想看看它對程式碼中的哪些地方進行了改動的話,可以使用--diff引數,執行black --diff 檔名稱,black會將相關資訊輸出到控制檯(下圖,其中-表示原始碼,+表示建議修改後的程式碼),而不會對原檔案進行修改。

總之,black真的是一個非常好用的庫,尤其對於新手來說,可以很方便地規範自己的程式碼風格。