Python學(xué)了好久,但是拿出來(lái)review的代碼好像總是長(zhǎng)的不夠俊美,不夠工整!因此標(biāo)準(zhǔn)化的代碼規(guī)范就顯得尤為重要囚戚。今天就來(lái)推薦3個(gè)利器,python界廣泛認(rèn)同的代碼風(fēng)格規(guī)范PEP8和兩個(gè)超牛的工具pylint和black轧简,分別用于代碼風(fēng)格規(guī)范檢測(cè)和自動(dòng)優(yōu)化驰坊。
1、代碼風(fēng)格規(guī)范PEP8
首先講一講為什么要使用PEP8哮独,我們先來(lái)看下面這段代碼拳芙,在相關(guān)函數(shù)定義后,它是可以正常編譯執(zhí)行的皮璧,但是 這段代碼的怪異風(fēng)格無(wú)論是讓別人閱讀還是自己閱讀都會(huì)感到很難受舟扎。這就需要一種普遍認(rèn)同的代碼風(fēng)格規(guī)范,對(duì)行長(zhǎng)度悴务、縮進(jìn)睹限、多行表達(dá)式、變量 命名約定等內(nèi)容進(jìn)行統(tǒng)一讯檐,這就是PEP8的意義所在羡疗。
需要說(shuō)明的是,PEP 8中有一些規(guī)范是為了方便閱讀别洪,而有一些規(guī)范實(shí)實(shí)在在地影響著代碼的性能叨恨、容錯(cuò)率或者重 構(gòu)難度。
比如上面這段代碼挖垛,foo函數(shù)僅在滿(mǎn)足條件的情況下有返回值痒钝、bar函數(shù)僅在不滿(mǎn)足條件的情況下有返回值秉颗,這樣的代碼兼容性會(huì)比較差,正確的做法是保持代碼一致性午乓,函數(shù)中的返回語(yǔ)句都應(yīng)該返回一個(gè)表達(dá)式站宗,或者都不返回:
關(guān)于PEP8就簡(jiǎn)單介紹到這里闸准,有興趣的朋友可以自行查閱文檔益愈。當(dāng)我們打開(kāi)文檔的時(shí)候會(huì)發(fā)現(xiàn)PEPE 8規(guī)范的內(nèi)容非常多、非常細(xì)夷家。
作為一名新手如果要一條條解讀蒸其、一條條記住這些規(guī)定實(shí)在不是件容易的事情。然而養(yǎng)成良好的 代碼編寫(xiě)習(xí)慣對(duì)新手來(lái)說(shuō)又是十分重要的库快。
下面我們就正式進(jìn)入主題摸袁,介紹兩個(gè)簡(jiǎn)單又實(shí)用的代碼自動(dòng)化檢測(cè)和優(yōu)化工具,可以幫助我們快速規(guī)范自己的代碼風(fēng)格义屏。
2靠汁、自動(dòng)檢測(cè)工具Pylint
Pylint 是一個(gè)檢查違反 PEP8 規(guī)范和常見(jiàn)錯(cuò)誤的庫(kù),它會(huì)自動(dòng)查找不符合代碼風(fēng)格標(biāo)準(zhǔn)和有潛在問(wèn)題的代碼闽铐,并在控制臺(tái)輸出代碼中違反規(guī)范和出現(xiàn)問(wèn)題的相關(guān)信息蝶怔。
1).安裝與使用
與python的其他庫(kù)一樣,直接 pip install pylint 即可完成安裝兄墅,另外anaconda自帶pylint踢星,所以如果安裝過(guò)anaconda不必再單獨(dú)安裝此庫(kù)。
pylint的使用也非常簡(jiǎn)單隙咸,最基本的用法直接在控制臺(tái)輸入 pylint 路徑/模塊名 即可對(duì)相關(guān)模塊的代碼風(fēng)格規(guī)范 進(jìn)行檢查沐悦,檢查結(jié)果會(huì)在控制臺(tái)輸出。
建議結(jié)合 pylint --help 的提示進(jìn)行 學(xué)習(xí)和檢索五督。介紹完pylint的基本情況藏否,我們來(lái)結(jié)合一個(gè)實(shí)例進(jìn)行詳細(xì)說(shuō)明。
2).實(shí)例演示說(shuō)明
這里我找了自己剛學(xué)python時(shí)寫(xiě)的一段代碼進(jìn)行測(cè)試:
乍一看好像沒(méi)什么大問(wèn)題充包,但是經(jīng)過(guò)pylint檢查后卻給出了一堆問(wèn)題提示(下圖)副签,我們來(lái)看檢查結(jié)果,每行以大 寫(xiě)字母+冒號(hào)開(kāi)頭的信息都是一處反饋提示误证。
其中開(kāi)頭的大寫(xiě)字母表示錯(cuò)誤類(lèi)型(主要有CRWEF幾類(lèi));以逗號(hào)間隔的兩個(gè)數(shù)字表示發(fā)現(xiàn)問(wèn)題的位置(行和 列);其后是對(duì)問(wèn)題的具體描述继薛,括號(hào)里的內(nèi)容稱(chēng)為message id,可以簡(jiǎn)單理解為錯(cuò)誤類(lèi)型的詳細(xì)分類(lèi)愈捅,通過(guò)
pylint --help-msg=<msg-id> 指令可以查看這個(gè)問(wèn)題的的詳細(xì)信息 遏考。
C——違反代碼風(fēng)格標(biāo)準(zhǔn);
R——代碼結(jié)構(gòu)較差;
W——關(guān)于細(xì)節(jié)的警告;
E——代碼中存在錯(cuò)誤;
F——導(dǎo)致Pylint無(wú)法繼續(xù)運(yùn)行的錯(cuò)誤。
例如蓝谨,我們執(zhí)行 pylint --help-msg=trailing-newlines 指令灌具,會(huì)在控制臺(tái)輸出對(duì) trailing-newlines 這種問(wèn)題的詳細(xì)描述:
pylint輸出的最后一行是其對(duì)本次檢測(cè)的評(píng)分青团,滿(mǎn)分為10分,可以看到我的代碼本次評(píng)分為0分T_T咖楣。
既然知道了自 己的代碼哪里不規(guī)范督笆,就去針對(duì)性地改正吧,根據(jù)提示結(jié)果首先將函數(shù)參數(shù)賦值 = 兩邊的空格去掉诱贿,再將多余的空 行去掉娃肿,然后運(yùn)行一下pylint再次進(jìn)行檢測(cè),得到如下結(jié)果:
可以看到珠十,剛才修改過(guò)的代碼相關(guān)問(wèn)題提示已經(jīng)沒(méi)有了料扰,評(píng)分也從0分提高到了3.33分。但是仍然有很多問(wèn)題焙蹭,這里就要注意了菊卷,PEP8并不是要百分百遵守的祭芦,當(dāng)遵循PEP 8規(guī)范會(huì)使代碼可讀性變差钦睡、會(huì)跟周?chē)a風(fēng)格不一致的時(shí)候钧嘶,還是要遵循自己的判斷。
這種情況下撰豺,pylint也提供了一種操作粪般,可以手動(dòng)屏蔽某些問(wèn)題提示,以剛才的代碼為例郑趁,剩下的幾個(gè)問(wèn)題主要是因?yàn)槭褂昧薚ab鍵刊驴、變量命名不規(guī)范、缺少文檔說(shuō)明造成的寡润,我們可以使用
pylint --disable=mixex-indentation,invalid-name,missing-docstring 模塊名稱(chēng) 命令對(duì)相關(guān)規(guī)范進(jìn)行屏蔽重新檢 測(cè)捆憎,發(fā)現(xiàn)問(wèn)題提示全部消除,評(píng)分也提升到了10分梭纹。
一段20行的代碼就檢測(cè)到如此之多的問(wèn)題提示躲惰,雖然手動(dòng)修改代碼有助于對(duì)PEP 8規(guī)范的學(xué)習(xí),但當(dāng)項(xiàng)目文件比較 多变抽、腳本代碼很長(zhǎng)的時(shí)候础拨,實(shí)在是一個(gè)不小的工作量,因此就出現(xiàn)了能夠自動(dòng)優(yōu)化代碼風(fēng)格的工具绍载。
3诡宗、自動(dòng)優(yōu)化工具Black
在眾多代碼格式化工具中,Black算是比較新的一個(gè)击儡,它最大的特點(diǎn)是可配置項(xiàng)比較少塔沃,個(gè)人認(rèn)為這對(duì)于新手來(lái)說(shuō)是件好事,因?yàn)槲覀儾槐剡^(guò)多考慮如何設(shè)置Black阳谍,讓 Black 自己做決定就好蛀柴。
1).安裝與使用
與pylint類(lèi)似螃概,直接pip install black即可完成該模塊的安裝,不過(guò)black依賴(lài)于Python 3.6+鸽疾,但它仍然可以格式化Python2的代碼吊洼。
在使用方面black默認(rèn)讀取指定python文件并對(duì)其進(jìn)行代碼規(guī)范格式化,然后輸出到原文件制肮。
例如冒窍,我們將上面這段代碼保存為test.py,然后在控制臺(tái)執(zhí)行 black test.py 指令弄企,再次打開(kāi)test.py超燃,發(fā)現(xiàn)其中 的代碼變成了這個(gè)樣子:
l = [1, 2, 3]
當(dāng)然,Black的封裝程度再高也是有自定義配置項(xiàng)的拘领,例如使用--version查看版本、使用--help查看幫助信息樱调、使用--diff將修改信息輸出到控制臺(tái)而不更改原文件约素,下面我們還是結(jié)合一個(gè)實(shí)例來(lái)進(jìn)行演示說(shuō)明。
2).實(shí)例演示說(shuō)明
這里我們?nèi)匀皇褂胮ylint部分的代碼進(jìn)行演示笆凌。通過(guò)上面的操作我們知道圣猎,對(duì)這段代碼直接使用pylint進(jìn)行測(cè)試會(huì)輸出很多問(wèn)題提示,并給出一個(gè)評(píng)分0∑蚨現(xiàn)在我們首先使用black對(duì)其進(jìn)行格式化送悔,得到以下代碼:
可能看起來(lái)修改前后的代碼差異并不十分明顯,實(shí)質(zhì)上black已經(jīng)對(duì)代碼中參數(shù)賦值 = 兩端的空格爪模、注釋的格式欠啤、 制表符等進(jìn)行了替換和修改,我們使用pylint來(lái)進(jìn)行驗(yàn)證屋灌,執(zhí)行 pylint 模塊名稱(chēng) 命令洁段,得到如下結(jié)果:
可以看到,相對(duì)于最初的文件共郭,評(píng)分從0分提高到7.3分祠丝,輸出的問(wèn)題提示少了很多,剩余的問(wèn)題主要是缺少說(shuō)明文檔除嘹、變量命名不規(guī)范.black對(duì)于提高我們代碼規(guī)范性?xún)r(jià)比也是非常高的写半。
如果不想black直接對(duì)原文件進(jìn)行修改,而是想看看它對(duì)代碼中的哪些地方進(jìn)行了改動(dòng)的話(huà)尉咕,可以使用--diff參數(shù)叠蝇,執(zhí)行black --diff 文件名稱(chēng),black會(huì)將相關(guān)信息輸出到控制臺(tái)(下圖龙考,其中-表示源代碼蟆肆,+表示建議修改后的代碼)矾睦,而不會(huì)對(duì)原文件進(jìn)行修改。
總之炎功,black真的是一個(gè)非常好用的庫(kù)枚冗,尤其對(duì)于新手來(lái)說(shuō),可以很方便地規(guī)范自己的代碼風(fēng)格蛇损。