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

前言

個人工程實踐項目爲金融文本數據挖掘,本項目涉及的網絡爬蟲、語義分析、金融相關知識。而在網絡爬蟲與語義分析這方面,python的案例特別多。因此我在github找了一份python的源代碼,項目名叫Financial_Analysis。python

看代碼前

分析前咱們能夠查看項目目錄下的README.md,在項目根目錄下的README.md中會對本項目進行要給大體的分析,但是從本代碼中的README.md中能夠看到,做者對本項目的解釋並很少,甚至都沒告訴咱們要運行的環境。git

README正確作法

爲了給他人更容易瞭解咱們的項目,在咱們上傳項目的README.md中,咱們應該在READEME.md中首先寫關於本項目解決的問題,以及用到的技術。接下來咱們則應該寫出本項目須要哪些環境,最後咱們則應該解釋運行步驟。由於有些項目的運行過程是比較麻煩的。用詳細的項目解釋,給人以方便,才能獲取更多的star。github

image

分析代碼

在瞭解完項目作了哪些功能後,咱們就進入代碼分析的階段。咱們要線看代碼的目錄結構,通常好的代碼目錄結構會對應它的功能模塊。因此咱們就能夠根據目錄結構知道某個功能在哪裏實現,而後咱們就能夠逐個功能模塊的代碼來分析。而其餘目錄結構中與咱們分析的功能無關,則可暫時放在旁邊。網絡

image

如上圖的目錄結構,他將項目分了三個目錄。這三個目錄就對應了三個功能。例如Scrapy對應分佈式爬蟲模塊,Fama-French-choose-stock-master對應金融數據挖掘,news-emotion-master對應文本挖掘技術。固然咱們可能從三個模塊的文件名看不出對應的功能。例如Fama-French-choose-stock-master,乍一看是看不出來這個模塊作的啥東西。分佈式

命名正確作法

咱們在命名文件名或者變量名的時候,必定要作到用一個通俗的單詞。不該該用拼音,也不該該隨便本身弄個單詞縮寫。例如上面圖中Fama-French-choose-stock-master中的Fama究竟是什麼意思呢?要用單詞縮寫的話,必定是你們都默認的縮寫,而不是本身隨便取一個縮寫。若是真的要這麼作,必定要在旁邊寫上註釋。對於變量命名有時候有些語言會推薦駝峯結構,因此咱們寫代碼的時候最好要按照語言推薦的方法去使用駝峯結構或者其餘風格。模塊化

代碼格式

# --------------計算SMB HML RM
def getData(mcStockDf,drStockDf,bmStockDf,sz50Df):
    # 取某段時期全部股票
    stocks = mcStockDf.columns.values
    # 轉置處理
    mcStockDf = mcStockDf.T
    bmStockDf = bmStockDf.T
    # 選取某一列做爲基準
    mcStockDf = mcStockDf.iloc[:,0:1]
    bmStockDf = bmStockDf.iloc[:,0:1]
    # 取列名
    sortName = mcStockDf.columns
    # 排序
    mcStockDf = mcStockDf.sort_values(by=sortName[0])
    bmStockDf = bmStockDf.sort_values(by=sortName[0])
    # 取當前股票總數
    amount = len(mcStockDf)
    # 選取大市值股票組合
    B = mcStockDf[int(amount-amount/3):].index
    B = B.values
    # 選取小市值股票組合
    S = mcStockDf[:int(amount/3)].index
    S = S.values
    # print(S.values)
    # 選取高bm的股票組合
    H = bmStockDf[int(amount-amount/3):].index
    H = H.values
    # 選取低bm的股票組合
    L = bmStockDf[:int(amount/3)].index
    L = L.values
    # print(L)
      # 求因子的值
    SMB = drStockDf[S][1:].sum(axis=1) / len(S) - drStockDf[B][1:].sum(axis=1) / len(B)
    HML = drStockDf[H][1:].sum(axis=1) / len(H) - drStockDf[L][1:].sum(axis=1) / len(L)
    # print(SMB)
#     基準收益率  上證50指數
    # print(sz50Df)
    RM = np.diff(np.log(sz50Df['close']))-0.04/252
    # print(len(RM))
    X = pd.DataFrame({"RM": RM, "SMB": SMB, "HML": HML})
    # 取前g.NoF個因子爲策略因子
    factor_flag = ["RM", "SMB", "HML"]
    X = X[factor_flag]
    # 對樣本數據進行線性迴歸並計算ai
    t_scores = [0.0] * amount
    # 循環依次計算股票的分數
    for i in range(0,amount):
        t_stock = stocks[i]
        sample = pd.DataFrame()
        t_r = linreg(X, drStockDf[t_stock][1:] - 0.04 / 252, len(factor_flag))
        t_scores[i] = t_r[0]
    # 這個scores就是alpha
    scores=pd.DataFrame({'code':stocks,'score':t_scores})
    # 根據分數進行排序
    scores = scores.sort_values(by='score')
    # print (scores.sort_values(by='score'))
    return scores

具體代碼格式能夠看到在python裏面是不使用大括號的,咱們是用縮進格式來控制函數範圍。因此咱們在控制縮進的時候必定要當心,多一個空格少一個空格就報錯。並且在這裏咱們不推薦使用tab鍵縮進。由於有的地方tab縮進格式不一樣。因此在你本機上可能能跑,在別人的電腦上用不一樣的編譯器可能就亂七八糟的。並且上面的這個函數一個函數就61行,這是很恐怖的。函數

函數的正確作法

對於函數,咱們推薦的作法是一個函數應該控制在20行代碼左右。這樣會讀者更加容易分析代碼。網上就有個段子一個類中幾萬行代碼,這樣的代碼咱們很難以模塊化的方法去閱讀。並且這種很長的函數,咱們應該給一個註釋,註釋中咱們要說到代碼的參數分別表明什麼意思,返回值是什麼東西,過程作了什麼。編碼

python語言命名特色

python命名規則與其餘語言有很大的不一樣,例如__init__(self)函數,這種以__開頭與結尾的函數我python類庫中一些特殊的函數。因此咱們在寫一個函數時儘可能不要用__開頭和結尾。只以__開頭的函數和變量則是表明着私有的函數與變量,可是python知識將其名稱改成了_類名__name,因此咱們在看到這種格式的函數與屬性的時候,切記不要調用。調用則會破壞程序的封裝性。而以單下劃線_開頭的命名通常用於模塊中的"私有"定義的命名。code

文件編碼

因爲中文的特殊性,不少時候編碼格式不對,會致使別人下載代碼後中文亂碼。因此咱們建立文件的時候必定要用UTF-8編碼,這是大部分人使用的編碼格式。在python中,例如在文件頭重加blog

#encoding:utf-8

總結

根據這套代碼咱們能發現很多缺點,也有不少優勢。可是咱們眼中不能只看優勢,在寫代碼的時候,很容易就被本身的習慣矇蔽過去,而後致使不少部分有這樣有那樣的不規範。咱們要想寫一個好的代碼,無論技術多難,寫代碼就像寫字,要時刻記住這些規範。

相關文章
相關標籤/搜索