part1.編寫高質量Python代碼的59個有效方法

PS:整理自書籍《Python 編寫高質量Python代碼的59個有效方法》,僅供學習整理使用

Cha 1 用Pythonic方式來思考

TIP 1 確認自己所用的Python版本

TIP 2 遵循PEP8風格指南

1.使用space來表示縮進,而不要使用tab

2.文件中的函數和類之間應該用兩行空格隔開

3.在同一個類中,各方法之間應該用一個空行隔開

4.在使用下標來獲取列表元素,調用函數或給關鍵字參數賦值的時候,不要在兩旁添加空格

5.函數變量及屬性應該用小寫字母來拼寫,各單詞之間以下劃線相連,例如,lowercase_underscore

6.受保護的實例屬性,以單個下劃線開頭,例如,_leading_underscore

7.私有的實例屬性,應該以兩個下劃線開頭,例如,__double_leading_underscore

8.類與異常,應該以每個單詞首字母均大寫的形式來命名,例如,CapitalizedWord

9.模塊級別的常量,應該全部采用大寫字母來拼寫,各個單詞之間以下劃線相連,例如。ALL_CAPS

10.類中的實例方法,應該吧首個參數命名為self,以表示該對象自身

11.類方法的首個參數,應該命名為cls,以表示該類自身。

12.每行的字符數不應超過79,可用反斜線和小括號進行多行代碼的連接

13.對于占據多行的長表達式來說,除了首行之外的其余各行都應該在通常的縮進級別上再加4個空格

14.采用內聯形式的否定詞,而不要把否定詞放在整個表達式的前面

15.不要通過檢測長度的辦法來判斷是否為空值

16.關于模塊的引入

TIP 3 了解bytes,str與unicode的區別

TIP 4 用輔助函數來取代復雜的表達式

1.開發者很容易過度運用Python的語法特性,寫出特別復雜并且難以理解的單行表達式。

2.把復雜的表達式移入輔助函數之中。

3.使用if、else表達式,比使用or或者and的Boolean操作符寫成的表達式更加清晰

TIP 5 了解切割序列的辦法

1.不要寫多余的代碼:當start索引為0,或end索引為序列長度時,應該將其省略

2.切片操作不會計較start與end是否越界

3.對list賦值的時候,如果使用切片操作,就會把原列表中處在相關范圍內的值替換成新值,即便長度不同亦可替換。

TIP 6 在單次切片操作內,不要同時指定start、end、和stride

1.既有start ,end又有 stride的切割操作,可能會令人費解。

2.盡量使用stride為正數,且不帶start或end索引

3.在同一個切片操作內,不要同時使用start,end和stride,如果確實需要執行,考慮將其拆解為兩條賦值語句,其中一條范圍切割,另一條做步進切割,或考慮使用內置itertools模塊中的islice

TIP 7 用列表推導來取代map和filter

a = [1,2,3,4,5,6,7,8]

square = [x**2 for x in a]

print(square)

1.列表推導要比內置的map和filter函數清晰,因為它無需額外編寫lambda表達式

2.列表推導可以跳過輸入列表中的某些元素,如果改用map來做就必須輔以filter方能實現

3.字典與集合也支持推導表達式

TIP 8 不要使用含有兩個以上表達式的列表推導

eg: matrix = [[1,2,3],[4,5,6],[7,8,9]]

flat = [x for row in matrix for x in row]??

squared = [[x**2 for x in row] for row in matrix]

print(flat)? # flat = [1,2,3,4,5,6,7,8,9]

print(squared) # squared = [[1,4,9],[16,25,36],[49,64,81]]

條件語句亦可加入至列表推導式

a = [1,2,3,4,5,6,7,8,9,10]

b = [x for x in a if x > 4 if x % 2 == 0]

c =??[x for x in a if x > 4 and x % 2 == 0]

此處if 和 and作用一樣,b和c的結果等價

1.列表推導支持多級循環,每一級循環也支持多項條件

2.超過兩個表達式的列表推導很難理解,應該盡量避免

TIP 9 用生成器表達式來改寫數據量較大的列表推導

列表推導的缺點:在推導過程中,對于輸入序列的每個值來說,可能都要創建僅含一項元素的全新列表,當數據非常多時,可能會消耗大量內存,導致程序崩潰。

按照列表推導的寫法寫迭代器,將中括號換成小括號,即可得到迭代器,結合next函數生成所需要的值。

eg: it = (len(x) for x in open('/tmp/my_file.txt'))

print(it)

print(next(it))

1.當輸入的數據量較大時,列表推導可能會因為占用太多內存而出問題

2.由生成器表達式所返回的迭代器,可以逐次產生輸出值,避免內存用量問題

3.把某個生成器表達式所返回的迭代器,放在另一個生成器表達式的for子表達式中,即可將二者組合起來

4.串在一起的生成器表達式執行速度很快

TIP 10 盡量用enumerate取代range

1.enumerate函數提供了一種精簡的寫法,可以在遍歷迭代器時獲知每個元素的索引

2.盡量用enumerate來改寫那種將range與下標訪問相結合的序列遍歷代碼

3.可以給enumerate提供第二個參數,以指定開始計數時所用的值(默認為0)

TIP 11 用ZIP函數同時遍歷兩個迭代器

1.內置的zip函數可以平行地遍歷多個迭代器

2.Python3的zip相當于生成器,會在遍歷過程中逐次產生元祖,而Python2中的zip則是直接把這些元祖完全生成好,并一次性返回整份列表。

3.如果提供的迭代器長度不等,那么zip就會自動提前終止

4.itertools內置模塊中的zip_longest函數可以平行遍歷多個迭代器,而不用在乎它們的長度是否相等。

TIP 12 不要在for和while循環后面寫else塊

1.Python有種特殊語法,可在for及while循環的內部語句塊之后緊跟一個else塊

2.只有當整個循環主體都沒遇到break語句時,循環后面的else塊才會執行

3.不要在循環后面使用else塊,因為這種寫法既不直觀又容易引起誤解

TIP 13 合理利用try/except/else/finally結構中的每個代碼塊

try/finally結構,確保程序能夠可靠地關閉文件句柄。

handle = open('/tmp/random_data.txt')

try:

? ? data = handle.read()

finally:

? ? handle.close()

1.無論try塊是否發生異常,都可以利用try/finally復合語句中的finally塊來執行清理工作

2.else塊可以用來縮減try塊中的代碼量,并把沒有發生異常時所要執行的語句與try/except代碼塊隔開

3.順利運行try塊后,若想使某些操作能在finally塊的清理代碼之前執行,則可將這些操作寫到else塊中。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容