學(xué)會(huì)合理分解代碼提高可讀性_第1頁(yè)
學(xué)會(huì)合理分解代碼提高可讀性_第2頁(yè)
學(xué)會(huì)合理分解代碼提高可讀性_第3頁(yè)
學(xué)會(huì)合理分解代碼提高可讀性_第4頁(yè)
學(xué)會(huì)合理分解代碼提高可讀性_第5頁(yè)
已閱讀5頁(yè),還剩20頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

27-學(xué)會(huì)合理分解代碼,提高代碼可讀 深入到細(xì)節(jié)代碼,無(wú)需注釋也能理解清清楚楚。而有些人,代碼勉勉強(qiáng)強(qiáng)能跑起來(lái),遇到稍微復(fù)雜的情況可能就會(huì)出;深入到代碼中eu,則發(fā)現(xiàn)處處都是魔術(shù)數(shù)、函數(shù)堆在起。個(gè)文件上千行,設(shè)計(jì)模式又是,讓人實(shí)在很難閱讀,更別提修和迭發(fā)。uidovanRossum(范姆,to創(chuàng)始人),代的閱讀頻遠(yuǎn)高于編代碼的頻。畢PEP8上節(jié)課我們簡(jiǎn)單提起過(guò)PEP8PEP是PythonEnhancementProposal的縮寫(xiě),翻譯過(guò)來(lái)叫“Python增強(qiáng)規(guī)范”。正如我們寫(xiě)文章,會(huì)有句式、標(biāo)點(diǎn)、段落格式、開(kāi)頭縮進(jìn)等標(biāo)準(zhǔn)的規(guī)范樣,Python書(shū)寫(xiě)自然也有套較為的規(guī)范。PEP8就是這樣種規(guī)范,它存在的意義,就是讓Python更易閱讀,換句話,增強(qiáng)代碼可讀性。事實(shí)上,Pycharm已經(jīng)內(nèi)置了PEP8規(guī)范檢測(cè)器,它會(huì)自動(dòng)對(duì)編碼不規(guī)范的地方進(jìn)行檢查,然后錯(cuò)誤,并推薦修改方式。下面這就是其界面。因此,在學(xué)習(xí)今天的內(nèi)容時(shí),我推薦你使用camE進(jìn)行代碼檢查,看 下自己的代碼格式哪里有問(wèn)題。尤其對(duì)于初學(xué)者,從某些程度來(lái)說(shuō),代碼規(guī)范甚至是比代碼準(zhǔn)確更重要的事情,因?yàn)閷?shí)際工作中,代可讀性的重要性 定比你多得多??s進(jìn)規(guī)Python和C++/Java最大的不同在于,后者完全使用大括號(hào)來(lái)區(qū)分代碼塊,而前者依靠不和不同的縮進(jìn)來(lái)進(jìn)行分塊。有個(gè)很有名的比賽,叫作C語(yǔ)言代碼大賽,其中有很多非常的作品,你能看到書(shū)寫(xiě)的代碼拍成各種形狀,有的是幅畫(huà),或者個(gè)卡通頭像,但是能執(zhí)行出驚人的結(jié)果。而放到Python,顯然就不能實(shí)現(xiàn)同樣的技巧了。不過(guò),以小換大,我們有了“像閱讀英語(yǔ)”樣清晰的Python代碼,也還是可以接受的話說(shuō)回來(lái),Python縮進(jìn)其實(shí)可以寫(xiě)成很多種,Tab、雙空格、四空格、Tab合等。而PEP8規(guī)范告訴我們,請(qǐng)選擇四個(gè)空格的縮進(jìn),不要使用Tab,更不要Tab和空格混著用。第二個(gè)要注意的是,每行最大長(zhǎng)度請(qǐng)限制在79個(gè)字符。 多個(gè)源代碼。如果某個(gè)源代碼的某些行過(guò)長(zhǎng),你就需要拖動(dòng)橫向滾動(dòng)條來(lái)閱讀,或者需要軟回車(chē)將本行內(nèi)放入 行,這就極大地影響了編碼和閱讀效率 后,行的內(nèi)容就很容易超過(guò)79個(gè)字符了。所以,這條規(guī)定另方面也在制約著程序員,不要寫(xiě)迭代過(guò)深空行規(guī)我們知道,Python中的空行對(duì)PythonP8另外,Python本身允許把多行合并為行,使用分號(hào)隔開(kāi),但這是PEP8推薦的做法。所以,即使是使用控制語(yǔ)句ifwhilefor,你的執(zhí)行語(yǔ)句哪怕只有行命令,也請(qǐng)另起行,這樣可以更大程度提升閱讀 空格規(guī) 函數(shù)的參數(shù)列表中,調(diào)用函數(shù)的參數(shù)列表中會(huì)出現(xiàn)逗號(hào),請(qǐng)注意逗號(hào)后要跟個(gè)空格,這是英語(yǔ)的使用習(xí)慣, 另外 對(duì)于操作符,例如+,-,*,/,&=,==,!=,請(qǐng)?jiān)趦蛇叾急A艨崭瘛2贿^(guò)與此對(duì)應(yīng),括號(hào)內(nèi)的兩端并換行規(guī)現(xiàn)在再回到縮進(jìn)規(guī)范,注意我們提到的第二點(diǎn),控制每行的最大長(zhǎng)度不超過(guò)79個(gè)字符,但是有時(shí)候,函數(shù)defsolve1(thisisthefirstparameter,thisisthesecondparameter,thisisthethirdparameter,thisistheforthparameter,thisisthefifthparameter,thisisthesixthdefsolve1(thisisthefirstparameter,thisisthesecondparameter,thisisthethirdparameter,thisistheforthparameter,thisisthefifthparameter,thisisthesixthreturn(thisisthefirstparameter+thisisthesecondparameter+thisisthethirdparameterthisistheforthparameter+thisisthefifthparameter+thisisthesixthdefsolve2(thisisthefirstparameter,thisisthesecondparameter,thisisthethirdparameter,thisistheforthparameter,thisisthefifthparameter,thisisthesixthreturnthisisthefirstparameter+thisisthesecondparameter+thisisthethirdparameter+thisthisistheforthparameter+thisisthefifthparameter+thisisthesixth(topsecret,,,,.launchnucleartopsecret,,,,.launchnuclear 個(gè)邏輯之下。solve1函數(shù) 第二種,則是通過(guò)換行符來(lái)實(shí)現(xiàn)。這個(gè)方法更為直接,你可以從solve2 下面的代碼選自開(kāi)源庫(kù)lwKa,為了更加直觀突出重點(diǎn),我刪去了注釋和大部分代碼,你意會(huì)即可。我希望,通過(guò)閱讀這段代碼,你能更了解到,前沿的項(xiàng)目是怎么在增強(qiáng)閱讀性上下功的。classclassModel(network.Network):deffit(self,batchsize=None,validationsplit=0.,validationdata=None,shuffle=rue,classweight=None,sampleweight=None,initialepoch=0,stepsperepoch=None,validationsteps=None,validationfreq=1,maxqueuesize=10,use#Legacyif'nbepoch'inkwargs:'he`nbepoch`argumentin`fit`hasbeenrenamed`epochs`.')epochs=kwargs.pop('nbepoch')ifraiseypeError('Unrecognizedkeywordarguments:'+str(kwargs))self.assertcompilewascalled()funcfunc=self.selecttrainingloop(x)returnfunc.fit(batchsize=batchsize,validationsplit=validationsplit,validationdata=validationdata,classweight=classweight,sampleweight=sampleweight,initialepoch=initialepoch,stepsperepoch=stepsperepoch,validationsteps=validationsteps,validationfreq=validationfreq,maxqueuesize=maxqueuesize,usemultiprocessing=use文檔規(guī)接下來(lái)我們說(shuō)說(shuō)文檔規(guī)范。先來(lái)看看最常用的import函數(shù)。首先,所有import盡量放在開(kāi)頭,這個(gè)沒(méi)什么說(shuō)的,畢竟到處import讓人很難看清楚文件之間的依賴關(guān)系,運(yùn)行時(shí)import也可能會(huì)導(dǎo)致潛在的效率問(wèn)題和其他風(fēng)險(xiǎn)。其次,不要使用import 次導(dǎo)入多個(gè)模塊。雖然我們可以在行中import多個(gè)模塊,并用逗號(hào)分隔,但請(qǐng)不要這么做。importtime,os是PEP8不推薦的做法。如果你采用frommoduleimportfunc這樣的語(yǔ)句,請(qǐng)確保func在本文件中不會(huì)出現(xiàn)命名。不過(guò),你其實(shí)可以通過(guò)frommoduleimportfuncasnew_func來(lái)進(jìn)行重命名,從而避免。注釋規(guī) 對(duì)于大的邏輯塊,我們可以在最開(kāi)始相同的縮進(jìn)處以#開(kāi)始寫(xiě)注釋。即使是注釋?zhuān)阋矐?yīng)該把它當(dāng)成完整的文章來(lái)書(shū)寫(xiě)。如果英文注釋?zhuān)?qǐng)注意開(kāi)頭大寫(xiě)及結(jié)尾標(biāo)點(diǎn),注意避免語(yǔ)法錯(cuò)誤和邏輯錯(cuò)誤,同時(shí)精簡(jiǎn)要達(dá)的意思。中文注釋也是同樣的要求。 份優(yōu)秀的代碼,離不開(kāi)優(yōu)秀的注釋。 行后面跟兩個(gè)空格,然后以#開(kāi)頭加入注釋。不過(guò),請(qǐng)注##hisisanexampletodemonstratehowtocomment.#Pleasenotethisfunctionmustbeusedcarefully.defifx==1:#hisisonlyoneexception.returnFalsereturnreturn文檔描再來(lái)說(shuō)說(shuō)文檔描述,我們繼續(xù)以TensorFlow的代碼為例。classSpatialDropout2D(Dropout):"""Spatial2DversionofDropout.hisversionperformsthesamefunctionasDropout,howeveritdropsentire2Dfeaturemapsinsteadofindividualelements.fadjacentpixelswithinfeaturemapsarestronglycorrelated(asisnormallythecaseinearlyconvolutionlayers)thenregulardropoutwillnotregularizetheactivationsandwillotherwisejustresultinaneffectivelearningratedecrease.nthiscase,SpatialDropout2Dwillhelppromoteindependencebetweenfeaturemapsandshouldbeusedinstead.rate:floatbetween0and1.Fractionoftheinputunitstodrop.dataformat:'channelsfirst'or'channelslast'.n'channelsfirst'mode,thechannelsdimension(thedepth)isatindex1,in'channelslast'modeisitatindextdefaultstothe`imagedataformat`valuefoundinyourKerasconfigfileat`~/.keras/keras.json`.fyouneversetit,thenitwillbe"channelslast".nputshape:4Dtensorwith`(samples,channels,rows,cols)`ifdataformat='channelsfirst'or4Dtensorwithshape:`(samples,rows,cols,channels)`ifdataformat='channelsOutputSameasinput[EfficientObjectLocalizationUsingConvolutional init(self,rate,dataformat=None,**kwargs):super(SpatialDropout2D,self).init(rate,**kwargs)ifdataformatisNone:dataformat=K.imagedataifdataformatnotin{'channelslast','channelsfirst'}:raiseValueError('dataformatmustbein''{"channelslast","channelsfirst"}')self.dataformat=dataformatself.inputspec=的返回值和格式,以及其他需要注意的地方。至于docstring的寫(xiě)法,它是用三個(gè)雙引號(hào)開(kāi)始、三個(gè)雙引號(hào)結(jié)尾。我們首先用 命名規(guī) 程序員來(lái)說(shuō),是個(gè)不算的事。個(gè)具有誤導(dǎo)性的名字,極有可能在項(xiàng)目中埋下潛在的bug。這里我就不從命名分類(lèi)方法來(lái)給你劃分了,我們只講些最實(shí)用的規(guī)范。先來(lái)看變量命名。變量名請(qǐng)使用abcd這樣毫無(wú)意義的單字符,我們應(yīng)該使用能夠代表其意思的變量名。般來(lái)說(shuō),變量使用小寫(xiě),通過(guò)下劃線串聯(lián)起來(lái),例 可以使用單字符的地方是迭代,比如foriinrange(n)這種,為了精簡(jiǎn)可以使用。如果是類(lèi)的私有變量,請(qǐng)記得前面增加兩個(gè)下劃線。對(duì)于類(lèi)名,則應(yīng)該首字母大寫(xiě),然后合并起來(lái),例如:classSpatialDropout2D()、class總之,還是那句話,不要過(guò)于個(gè)變量名的長(zhǎng)度。當(dāng)然,在合理描述這個(gè)變量背后代表的對(duì)象后, 編程中個(gè)思想,寫(xiě)重復(fù)碼重復(fù)代大率可以過(guò)用條件循、構(gòu)造數(shù)類(lèi)來(lái)解。而另個(gè)想則是,少迭代層,盡可能讓thon代碼平化,畢,人的大無(wú)法處理多的棧所以,在很多業(yè)務(wù)邏輯比較復(fù)雜的地方,就需要我們加入大量的判斷和循環(huán)。不過(guò),這些旦沒(méi)寫(xiě)好,程序看 ififiammoney=100money=10 ififiammoney=100money=再來(lái) defdefifisserverdead:LOG('serverdead')ifisservertimedout:LOG('servertimedout')result=getresultfromserver()ifresult==MONEYSNOLOG('youdonothaveenoughmoney')ifresult==RANSACONSUCCEED:LOG('somethingwrong') 下defdefifisserverdead:LOG('serverdead')ifisservertimedout:LOG('servertimedout')result=getresultfromifresult==MONE SNOENOUGH:LOG('youdonothaveenoughmoney')ifresult==RANSACONSUCCEED:LOG('something 這里,我以個(gè)簡(jiǎn)單的二分搜索來(lái)舉例說(shuō)明。我給定個(gè)非遞減整數(shù)數(shù)組,和個(gè)target,要求你找到數(shù)組中最小的個(gè)數(shù)x,可以滿足x*x>target。旦不存在,則返回-1。 defdefsolve(arr,target):l,r=0,len(arr) ret=whilel<=m=(l+r)//ifarr[m]*arr[m]>target:ret=mr= l=m+1ifret==1:returnreturnprint(solve([1,2,3,4,5,6],print(solve([1,2,3,4,5,6],print(solve([1,2,3,4,5,6],print(solve([1,2,3,4,5,6], 段代碼這樣的寫(xiě)法,在算法比賽和面試中已經(jīng)OK了。不過(guò),從工程角度來(lái)說(shuō),我們還能繼續(xù) defdefcomp(x,returnx*x>defbinarysearch(arr,target):l,r=0,len(arr) ret=whilel<=m=(l+r)//ifcomp(arr[m],target):ret=mr= l=m+1returnretdefsolve(arr,id=binarysearch(arr,ifid!=returnarr[id]return1print(solve([1,2,print(solve([1,2,3,4,5,6],print(solve([1,2,3,4,5,6],print(solve([1,2,3,4,5,6],print(solve([1,2,3,4,5,6],你可以看出,第二段代碼中,我把不同功能的代碼拿了出來(lái)。其中,)函數(shù)作為判斷,拿出來(lái)后可以讓整個(gè)程序更清晰;同時(shí),我也把二分搜索的主程序拿了出來(lái),只負(fù)責(zé)二分搜索;最后的ve()拿到結(jié)果,決定返回不存在,還是返回值。這樣來(lái),每個(gè)函數(shù)各司其職,閱讀性也能得到定提高。 : init(self,=,age,jobtitle,job self.age=ageself.jobtitle=jobtitleself.jobdescription=descriptionpanyname 你應(yīng)該能看得出來(lái),job在其中出現(xiàn)了很多次,而且它們表達(dá)的是個(gè)意義實(shí)體,這種情況下,我們可以考: init(self,=,age,jobtitle,job self.age=ageself.job=Job(jobtitle,job class init(self,jobtitle,jobself.jobtitle=jobtitleself.jobdescription=descriptionpanyname 今天這節(jié)課,我們簡(jiǎn)單講述了如何提高Python代碼的可讀性,主要介紹了PEP8規(guī)范,并通過(guò)實(shí)例的說(shuō)明和改造,讓你清楚如何對(duì)Python程序進(jìn)行可讀性優(yōu)化。最后, 規(guī)范問(wèn)題而犯下的錯(cuò)誤,和這些錯(cuò)誤會(huì)導(dǎo)致什么樣的,比如對(duì)后來(lái)讀代碼的人有嚴(yán)重的誤導(dǎo),或是埋下了潛在的bug等等。希望你在留言區(qū)你的經(jīng)歷,你也可以把這篇文章出去,讓的人互相交流心得體會(huì),留下真實(shí)的oWorld2019-07-11 個(gè)空 個(gè)空 當(dāng)使用控制語(yǔ)句if/while/for時(shí),即使執(zhí)行語(yǔ)句只 個(gè)空 個(gè)空列表、元組、字典的元間要 個(gè)空 個(gè)空使用#注釋的話,#后要 個(gè)空 般我們通過(guò)代碼邏輯拆分等來(lái)控制每行的最大長(zhǎng)度不超過(guò)79字時(shí)還是不可避免的會(huì)超過(guò)這個(gè)限制,這個(gè)時(shí)候就需要通過(guò)換行來(lái)解決問(wèn)題了。 所有import盡量放在代碼文件的頭每行import只導(dǎo) 個(gè)對(duì)當(dāng)我們使用fromxxximportxxx時(shí),import后面跟著的對(duì)象要是 個(gè)類(lèi)或者個(gè)函數(shù) 行的相同縮進(jìn)處以#開(kāi)始書(shū)寫(xiě)注代碼行注釋?zhuān)诖a行的尾部跟2 變量名,要全部小寫(xiě),多個(gè)詞通過(guò)下劃線連接,可以使用單字符變量名的場(chǎng)景,比如friina()這種變量沒(méi)有實(shí)際意義的情況 夜路破曉2019-07-10求時(shí)再來(lái)關(guān)注代碼規(guī)范之類(lèi)的問(wèn)題。 項(xiàng)個(gè)認(rèn)知:寫(xiě)漂亮代碼與寫(xiě)能跑起來(lái)的代碼之間不存在因果關(guān)系,兩者都是你需要花費(fèi)時(shí)間精力學(xué)習(xí)的內(nèi)容 點(diǎn),越能合理而高效地安排自己的學(xué)習(xí)計(jì)劃。[3贊new2019-07-10如果代碼邏輯清晰,加上注釋是錦上添花的事,相對(duì)寫(xiě)代碼和讀代碼,程序員更愿意自己寫(xiě)代碼,而在項(xiàng)目中又必須

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論