国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python編程規(guī)范筆記(上)

Kross / 1439人閱讀

摘要:編程規(guī)范筆記上寫在前面從語言開始,自己陸續(xù)學(xué)習(xí)了,但是自從研究生做畢設(shè)接觸以來,就愛不釋手,再也沒有動力嘗試其他語言。一與的一大優(yōu)勢就是具備優(yōu)秀的可讀性,而這基于一套較為完整的公認(rèn)編程規(guī)范。如原本希望的結(jié)果是,結(jié)果卻完全一樣。

Python編程規(guī)范筆記(上) 寫在前面:

從C語言開始,自己陸續(xù)學(xué)習(xí)了C++/Java,但是自從研究生做畢設(shè)接觸Python以來,就愛不釋手,再也沒有動力嘗試其他語言。然而慚愧的是,由于一直從事科研工作,因?yàn)楹苌訇P(guān)注代碼規(guī)范性與代碼效率,導(dǎo)致自己之前論文所做實(shí)驗(yàn)代碼可讀性極差。故而忙里抽閑得一半日,粗?jǐn)垺禤ython編程之美》,收貨頗豐,故而重做于屏幕前,權(quán)當(dāng)整理記錄。由于全書于己涉及知識點(diǎn)不少,故而僅挑選當(dāng)前急用者梳理之。

一、PEP_8與PEP_20

Python的一大優(yōu)勢就是具備優(yōu)秀的可讀性,而這基于一套較為完整的公認(rèn)編程規(guī)范。這里建議所有初學(xué)或使用Python的同學(xué),可以先從PEP_8入手,其中包括了命名、空格、換行以及函數(shù)參數(shù)等多個最常用最基本的編程規(guī)范。

以自己為例,通常命名變量都采取大小寫組合的形式,如一個表示用戶特征的變量,通常會命名為Users_Feats_lst,而閱讀了PEP_8之后才發(fā)覺這樣寫十分不美觀,導(dǎo)致讀起來十分混亂,推薦的命名規(guī)范是:

常量可以采用全大寫;

類名可以采用HelloWorld的單詞首字母大寫形式;

其余函數(shù)與變量名,全部推薦采用小寫形式;

上面是自己初讀完PEP_8立刻就用上的一點(diǎn)小規(guī)范,感覺很實(shí)用。因此建議大家在開始Python前抽出十分鐘先讀讀PEP_8/20,后者是對于前者的一個擴(kuò)充升級,不過我建議初學(xué)的同學(xué)先從8開始就可以了,逐步學(xué)習(xí)即可。

PEP8 -- Python代碼樣式指南(中文版)


二、一般性建議歸納

這部分我們就開始梳理感覺最實(shí)用的規(guī)范了。

2.1 明確勝于隱晦

Python中提供了同一功能的多種編碼實(shí)現(xiàn)方式,那么越明確越簡練的方式就越推薦。判斷代碼寫得是否優(yōu)雅的一個經(jīng)驗(yàn)法則是:其他開發(fā)者是否可以只閱讀函數(shù)的首行與末行就理解函數(shù)的作用。

2.2 留白勝于緊湊

Python一般要求一行僅寫一個語義句,避免多步處理寫在同一行;當(dāng)然,如果一個長參數(shù)函數(shù)可以在函數(shù)部分?jǐn)嘈?,如使用反斜?*或者小括號。

2.3 盡量僅在一處返回函數(shù)結(jié)果

當(dāng)遇到多情況的if-else判斷時,往往可以在每個判斷后返回結(jié)果,然而這與具有多重出口的迷宮一樣,會降低可讀性,故而一般要求函數(shù)寫成僅有一個返回return的形式。


三、約定 3.1 檢查相等性的替代方法

對于和邏輯變量以及0比較的情況,相等性檢查全部建議替換為直接使用if語句,如下述情況就推薦2)的形式。

1)if flag_0 == True:
    pass
2)if flag_0:
    pass
3.2 操作列表(列表解析與filter/map函數(shù))

一般而言循環(huán)操作列表時我們都喜歡使用以下方法,如從下述列表中篩選出大于等于4的元素:

a = range(10)
b = []
for ele in a:
    if a > 4:
        b.append(ele)
    else:
        continue
print b

然而,現(xiàn)在我們要推薦一種更為簡潔優(yōu)美的方法:列表解析

a = range(10)
b = [i + 2 for i in a if i > 4]
print b
-->[7, 8, 9, 10, 11]

即,我們只要遵循格式[ele operator | ele from where | ele condation]即可,進(jìn)一步地,上述代碼結(jié)果說明不僅可以設(shè)置篩選特定條件的元素,進(jìn)一步還可以對每個元素進(jìn)行運(yùn)算。

當(dāng)然,如果上面的公式你感覺別扭不容易讀,那么也可以使用同樣功能的函數(shù),只是篩選對應(yīng)filter(),運(yùn)算對應(yīng)map(),其中filter函數(shù)返回篩選條件為True的元素組成的新列表,而map函數(shù)返回函數(shù)操作結(jié)果組成的新列表。

c = filter(lambda x : x > 4, a)
print c
-->[5, 6, 7, 8, 9]
d = map(lambda x : x * x, a)
print d
-->0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
3.3 解包

解包操作主要用于已知列表或者元祖長度的情況下分配元素,其一般通用公式為:

taget_1, taget_2,...,target_N=長度N的列表或者元祖

需要注意的是,僅在Python 3.0以上版本中,才支持可變目標(biāo)參數(shù)的解包(Unpack)

3.4 創(chuàng)建一個包含N個相同對象的列表

你可能會想這還不簡單?但是其實(shí)很容易犯錯,我們先給出總結(jié)的規(guī)律:

若非可變對象*N,可以得到正確的N個相同對象的列表

對于空對象[]*N,結(jié)果依舊是空對象[]

對于可變對象[[]]*N,其結(jié)果默認(rèn)是N個指向同一個列表的對象列表

# case 1
four_nones = [None]
print four_nones * 4
-->[None, None, None, None]
# case 2
four_nones = []
print four_nones * 4
-->[]
# case 3
four_nones = [[]] * 4
print four_nones 
-->[[], [], [], []]
four_nones[0].append(1) # still be list, so save the copy attr
print four_nones
-->[[1], [1], [1], [1]]
four_nones[0] = 2 # changed to be integer not list
print four_nones
-->[2, [1], [1], [1]]
# suggest format: 列表解析
four_nones = [[] for i in range(4)]
four_nones[0].append(100)
print four_nones
-->[[100], [], [], []]

四、常見陷阱

所謂陷阱,自然是容易犯錯的部分,這里簡單梳理兩例。

4.1 可變的默認(rèn)參數(shù)

有些時候我們希望定義一個可供調(diào)用的函數(shù),其中包含一個可變參數(shù)以適應(yīng)不同調(diào)用場景。如:

# wrong case:
def append_to(ele, to=[]):
    to.append(ele)
    return to
my_list_1 = append_to(10)
print my_list_1
-->[10]
my_list_2 = append_to(20)
print my_list_2
-->[10, 20]

細(xì)心的同學(xué)可能發(fā)現(xiàn)了,我們本希望兩次函數(shù)調(diào)用分別得到[10]與[20],結(jié)果第二次執(zhí)行時卻保留了第一次執(zhí)行的結(jié)果,也就是說,雖然我們使用了可變參數(shù)作為默認(rèn)參數(shù),導(dǎo)致其并未在后續(xù)調(diào)用時刷新。Python在函數(shù)定義而非調(diào)用時自動計算其默認(rèn)參數(shù)。

一個解決的簡單方法是,直接設(shè)置一個默認(rèn)值表示沒有提供默認(rèn)參數(shù),而是每次重新初始化對象:

def append_to(ele, to=None):
    if to is None:
        to=[]
    to.append(ele)
    return to
my_list_1 = append_to(10)
print my_list_1
-->[10]
my_list_2 = append_to(20)
print my_list_2
-->[20]
4.2 延遲綁定的閉包

有些時候,我們希望可以采用循環(huán)的方式創(chuàng)建多個唯一性函數(shù),而這時候其中的循環(huán)變量帶來的延遲綁定可能導(dǎo)致錯誤。如:

# wrong case:
def create_multipliers():
    return [lambda x : x * i for i in range(5)]
for multiplier in create_multipliers():
    print multiplier(2)
-->8
-->8
-->8
-->8
-->8

原本希望的結(jié)果是[0,2,4,6,8],結(jié)果卻完全一樣。其原因在于for循環(huán)依次訪問函數(shù)對象列表時,肯定函數(shù)對象生成函數(shù)已經(jīng)完成,返回的函數(shù)對象中i值全部為4,因此導(dǎo)致結(jié)果一致。此時只需要多帶帶綁定一個默認(rèn)參數(shù)i_0,避免受到i值影響即可:

def create_multipliers():
    return [lambda x, i_0 = i : x * i_0 for i in range(5)]
for multiplier in create_multipliers():
    print multiplier(2)
-->0
-->2
-->4
-->6
-->8

五、小結(jié)

今天所梳理的部分集中在兩個方面:

列表解析帶來的列表循環(huán)操作的優(yōu)雅表達(dá)法以及創(chuàng)建N個相等對象列表時可能出現(xiàn)的淺復(fù)制問題,列表解析屬于深復(fù)制;

函數(shù)調(diào)用過程中默認(rèn)參數(shù)在定義時初始化而非調(diào)用時初始化,且循環(huán)創(chuàng)建唯一性函數(shù)時容易受到閉包綁定延遲帶來的影響導(dǎo)致程序錯誤;

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/44017.html

相關(guān)文章

  • AI開發(fā)書籍分享

    摘要:編程書籍的整理和收集最近一直在學(xué)習(xí)深度學(xué)習(xí)和機(jī)器學(xué)習(xí)的東西,發(fā)現(xiàn)深入地去學(xué)習(xí)就需要不斷的去提高自己算法和高數(shù)的能力然后也找了很多的書和文章,隨著不斷的學(xué)習(xí),也整理了下自己的學(xué)習(xí)筆記準(zhǔn)備分享出來給大家后續(xù)的文章和總結(jié)會繼續(xù)分享,先分享一部分的 編程書籍的整理和收集 最近一直在學(xué)習(xí)deep learning深度學(xué)習(xí)和機(jī)器學(xué)習(xí)的東西,發(fā)現(xiàn)深入地去學(xué)習(xí)就需要不斷的去提高自己算法和高數(shù)的能力然后...

    huayeluoliuhen 評論0 收藏0
  • JS學(xué)習(xí)筆記 - 模塊化

    摘要:在開發(fā)大型的項(xiàng)目中,可能會使用到管理的模塊化工具。說道,學(xué)習(xí)過的同學(xué)會比較熟悉,是服務(wù)器模塊的規(guī)范,采用了這個規(guī)范。可能是未來模塊化解決方案的首選。 本文章記錄本人在學(xué)習(xí) JavaScript 中理解到的一些東西,加深記憶和并且整理記錄下來,方便之后的復(fù)習(xí)。 在開發(fā)大型的web項(xiàng)目中,可能會使用到管理js的模塊化工具。但是在前端輪子漫天飛的時代。那一款js模塊化工具真正適合我...

    CntChen 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<