分析一套源代码的代码规范和风格并讨论如何改进优化代码

前言

个人工程实践项目为金融文本数据挖掘,本项目涉及的网络爬虫、语义分析、金融相关知识。而在网络爬虫与语义分析这方面,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

总结

根据这套代码咱们能发现很多缺点,也有不少优势。可是咱们眼中不能只看优势,在写代码的时候,很容易就被本身的习惯蒙蔽过去,而后致使不少部分有这样有那样的不规范。咱们要想写一个好的代码,无论技术多难,写代码就像写字,要时刻记住这些规范。

相关文章
相关标签/搜索