分析一套源代碼的代碼規範和風格並討論如何改進優化代碼

分析一套源代碼的代碼規範和風格並討論如何改進優化代碼python

1、結合工程實踐選題相關的一套源代碼,根據其編程語言或項目特色,分析其在源代碼目錄結構、文件名/類名/函數名/變量名等命名、接口定義規範和單元測試組織形式等方面的作法和特色git

我此次的工程實踐是圍繞密章檢測展開的,須要用到與目標檢測方面相關的知識,因而在github上找到了一套與此相關的代碼。這套代碼是基於python進行編程的,用到了pytorch框架和yolov3算法。github

一、源代碼目錄結構算法

 

從圖中能夠看出,源碼的目錄結構簡單清晰。編程

—assets/:存放原生資料文件,裏面存放的是一些圖片網絡

—config/:主要存放一些項目配置文件和命令文件框架

—data/:存放數據,包括訓練數據集和樣本圖片編程語言

—utils/:提供一些公共方法和輔助類方法的文件函數

—weights/:存放yolov3的配置文件和模型文件 單元測試

二、文件名/類名/函數名/變量名等命名

(1)文件名

detect.py:檢測目標

models.py:神經網絡模型

test.py:用來測試模型

train.py:用來訓練模型

README.md:簡要的描述該項目的信息,讓使用者快速瞭解這個項目

requirements.txt:經過requirements.txt來管理依賴庫

該項目中文件的命名仍是比較易讀的,根據命名就能夠大體瞭解這個文件主要是作什麼的,實現了什麼功能。同時經過README文件,使用者能夠知道在使用該項目時,應該作哪些準備以及如何正確使用項目。

(2)類名、函數名和變量名

 

以Darknet類爲例:這個類是nn.Module的子類,命名爲Darknet,接着進行一些初始化,網絡的前饋部分都是在foward的這個函數中完成的,pytorch會自動調用這個函數,首先,foward用來完成網絡從輸入到輸出的pipline,其次,將輸出的featuemap轉換爲更容易處理的形式。定義的forward函數如上所示,其包括三個參數,self,輸入x,和targets。關於yolo算法的類、函數和變量名的定義,其實已經漸漸造成了默認的標準,該項目的代碼也基本遵循了這些規範。

三、接口定義規範

該項目中並無明確地定義接口。實際上,python中無接口類型,定義接口只是一我的爲規定,在編程過程自我約束,在python中接口由抽象類和抽象方法去實現,接口是不能被實例化的,只能被別的類繼承去實現相應的功能。我的以爲接口在python中並無那麼重要,由於若是要繼承接口,須要把其中的每一個方法所有實現,不然會報編譯錯誤,還不如直接定義一個class,其中的方法實現所有爲pass,讓子類重寫這些函數。固然若是有強制要求,必須全部的實現類都必須按照接口中的定義寫的話,就必需要用接口。

廣義上來講,接口其實是定義一個規範、標準。不規範的代碼和開發習慣使工做中的大部分時間都在定位問題+改代碼,填堵遺留下來的坑,致使實際用於開發中的時間並很少,高質量、高效的代碼,能夠切實有效的提升工做效率,減小無謂的時間浪費。

四、單元測試組織形式

在目標檢測相關算法中,最重要的就是目標檢測的準確度,不只要對模型進行訓練,還要對訓練的結果進行準確度的測評。在該項目中,單獨使用一個test.py文件對模型訓練的結果進行測試。

 

2、列舉哪些作法符合代碼規範和風格通常要求

一、項目的目錄結構較好地遵循了項目開發的目錄規範,文件命名規範,一目瞭然。

二、代碼編排:

 

(1)縮進採用4個空格而非tab;

(2)類和top-level函數定義之間空兩行;類中的方法定義之間空一行

(3)每行不超過最大長度79

三、文檔編排:

 

一句僅import一個庫,採用from XX import XX引用庫時避免了命名衝突

四、註釋規範:

 

該項目中的註釋風格比較統一,基本都是使用"""來包圍註釋內容。

 

行註釋使用#。。。。

 

 

3、列舉哪些作法有悖於「代碼的簡潔、清晰、無歧義」的基本原則,及如何進一步優化改進

一、模塊、函數、類、方法的註釋過於簡潔,大部分函數基本沒有註釋,在讀代碼的時候比較費勁。

二、空行的做用就是隔離不一樣函數類等,使井井有條。在本項目的代碼中,不必的空行有點多

 

三、README.md文件只給了運行代碼的方式,安裝環境,啓動命令以及運行的效果進行說明,並無對項目的結構、項目中的代碼文件進行說明。

 

 

4、總結同類編程語言或項目在代碼規範和風格的通常要求

項目目錄規範:

經過規範化,可以更好的控制軟件結構,讓程序具備更高的可讀性。

參考的目錄結構:

 

個別說明:

README內容說明

1:軟件定位,軟件的基本功能

2:運行代碼的方式:安裝環境,啓動命令等。

3:簡要的使用說明。

4:代碼目錄結構說明,更詳細能夠說明軟件的基本原理

5:常見問題說明。

requirements.txt

文件格式是一行包含一個包依賴的說明,要求這個格式能被pip識別,使用方式:

pip install -r requirements.txt 來安裝全部依賴的包

以上各個目錄模塊如何動態導入,實現動態遷移。

Python代碼編寫規範:

一、代碼編排

(1)縮進。4個空格的縮進,不使用Tap,更不能混合使用Tap和空格。

(2)每行最大長度79,換行可使用反斜槓,最好使用圓括號。換行點要在操做符的後邊敲回車。

(3)類和top-level函數定義之間空兩行;類中的方法定義之間空一行;函數內邏輯無關段落之間空一行;其餘地方儘可能不要再空行。

二、文檔編排

(1)模塊內容的順序:模塊說明和docstring—import—globals&constants—其餘定義。其中import部分,又按標準、三方和本身編寫順序依次排放,之間空一行。

(2)不要在一句import中多個庫,好比import os, sys不推薦。

(3)若是採用from XX import XX引用庫,能夠省略‘module.’,均可能出現命名衝突,這時就要採用import XX。

三、空格的使用

整體原則,避免沒必要要的空格。

(1)各類右括號前不要加空格。

(2)逗號、冒號、分號前不要加空格。

(3)函數的左括號前不要加空格。如Func(1)。

(4)序列的左括號前不要加空格。如list[2]。

(5)操做符左右各加一個空格,不要爲了對齊增長空格。

(6)函數默認參數使用的賦值符左右省略空格。

(7)不要將多句語句寫在同一行,儘管使用‘;’容許。

(8)if/for/while語句中,即便執行語句只有一句,也必須另起一行。

四、註釋

整體原則,錯誤的註釋不如沒有註釋。因此當一段代碼發生變化時,第一件事就是要修改註釋,註釋必須使用英文,最好是完整的句子,首字母大寫,句後要有結束符,結束符後跟兩個空格,開始下一句。若是是短語,能夠省略結束符。

(1)塊註釋,在一段代碼前增長的註釋。在‘#’後加一空格。段落之間以只有‘#’的行間隔。好比:

# Description : Module config.

# Input : None

#

# Output : None

(2)行註釋,在一句代碼後加註釋。好比:x = x + 1  # Increment x。可是這種方式儘可能少使用。

(3)避免無謂的註釋。 

五、文檔描述

(1)爲全部的共有模塊、函數、類、方法寫docstrings;非共有的沒有必要,可是能夠寫註釋(在def的下一行)。

(2)若是docstring要換行,參考以下例子

"""Return a foobang

Optional plotz says to frobnicate the bizbaz first.

"""

六、命名規範

整體原則,新編代碼必須按下面命名風格進行,現有庫的編碼儘可能保持風格。

(1)儘可能單獨使用小寫字母‘l’,大寫字母‘O’等容易混淆的字母。

(2)模塊命名儘可能短小,使用所有小寫的方式,可使用下劃線。

(3)包命名儘可能短小,使用所有小寫的方式,不可使用下劃線。

(4)類的命名使用CapWords的方式,模塊內部使用的類採用_CapWords的方式。

(5)異常命名使用CapWords+Error後綴的方式。

(6)全局變量儘可能只在模塊內有效,相似C語言中的static。實現方法有兩種,一是__all__機制;二是前綴一個下劃線。

(7)函數命名使用所有小寫的方式,可使用下劃線。

(8)常量命名使用所有大寫的方式,可使用下劃線。

(9)類的屬性(方法和變量)命名使用所有小寫的方式,可使用下劃線。

(10)類的屬性有3種做用域public、non-public和subclass API,能夠理解成C++中的public、private、protected,non-public屬性前,前綴一條下劃線。

(11)類的屬性若與關鍵字名字衝突,後綴一下劃線,儘可能不要使用縮略等其餘方式。

(12)爲避免與子類屬性命名衝突,在類的一些屬性前,前綴兩條下劃線。好比:類Foo中聲明__a,訪問時,只能經過Foo._Foo__a,避免歧義。若是子類也叫Foo,那就無能爲力了。

(13)類的方法第一個參數必須是self,而靜態方法第一個參數必須是cls。

相關文章
相關標籤/搜索