什麼是pythonic的思考方式

最近在學習大神 slatkin 的高效編程指南,發現有不少細節以往本身都未曾注意過但倒是很是值得了解的。在這裏總結並分享給你們。html


1.遵循PEP8的編程風格python


 PEP8全稱《Python Enhancement Proposal #8》,又叫作8號python加強提案,經過規範編程風格,使得本身的代碼更加易懂,不一樣的開發人員之間能夠更高效地溝通。完整指南見:https://www.python.org/dev/peps/pep-0008/。比較經常使用的一點建議是:添加縮進時儘可能使用空格,tab鍵在不一樣的編程環境下,可能表明不一樣的空格數,不必定是四個空格。另外,Python的宗旨是:每件事都應該有直白的作法,並且最好只有一種。編程


2.注意bytes、str、unicode的區別網絡


首先須要瞭解的一點是:計算機在硬盤中存儲的數據格式以及網絡中傳輸的數據均爲bytes. 好比,你的電腦D盤中有個名爲test.txt的文本文件,那麼這個文件中的數據是以bytes的類型存儲在硬盤中的。以Python3爲例,當你將text.txt中的數據(文本或者數字),讀入內存,進行一些特定的處理或計算時,你須要將這些bytes類型的數據轉換爲Unicode類型,而後在你的Python代碼中盡情地執行各類計算和處理。同理,處理好以後的內容,你可能想寫出到硬盤中去保存起來,那麼你應該再將Unicode類型的數據轉爲bytes類型。函數

目前unicode和bytes之間相互轉換的編碼方式主要採用UTF-8,Python3中提供了encode()和decode()方法來實現編碼轉換。學習

上圖代碼的意思是:‘中文’ 這兩個漢字在硬盤中是以 b'\xe4\xb8\xad\xe6\x96\x87' 存儲的。當它被解碼(decode)以後,就以字符串(str) ‘中文’ 的形式展現。瞭解這些能夠幫助咱們在操做文件時,避免由於編碼混亂的問題,使得程序出現一些奇怪的報錯信息。網站

在工程實踐中,咱們在一段代碼中因須要的不一樣可能想操做不一樣的數據類型,好比有些狀況下咱們想操做二進制的bytes(如圖像像素),有些狀況下咱們想操做字符串str (如處理一些文本),這個時候,利用輔助函數在整個核心代碼塊的外圍將數據統一爲咱們須要的格式,會使得程序更靈活,例如,假設當前的核心代碼塊有可能接受str爲其輸入數據,也有可能接受bytes爲其輸入,爲了保證核心代碼塊內部操做的數據是一致的(不妨假設爲str),能夠經過以下輔助函數實現:編碼


3.要善於使用輔助函數spa


 Python的語法特別精煉,所以咱們很容易使用一行代碼來實現一些很精巧的操做,可是不建議過分使用這種特性,除非你編寫代碼不是爲了某個項目須要,而是爲了炫技。輔助函數也使得屢次利用重複的邏輯功能變得十分便捷。3d

好比上圖中這個字符串解析的例子,method1和method2都實現了從解析結果中查詢某個參數的功能,但method1經過輔助函數使得代碼更加易懂,而且能夠重複調用,查詢不一樣的參數時,只須要更改參數‘red’一次便可,而method2每更換一次查詢參數,至少須要改動三處才能實現。


 4.熟練掌握序列切割的技巧


 Python的切片操做相信不少人一開始接觸Python就已瞭解了一些,這裏只標註三點做爲示例:

(1)採用-1作步進值,能夠很容易將一個序列顛倒

(2)切割列表時,範圍能夠越界,Python會智能識別,可是用下表訪問元素時,不能越界

 

(3)Python支持用不一樣長度的列表去覆蓋原列表中的某些片斷


5.用列表推倒取代map和filter函數


在Python中,列表,字典,集合均支持推倒操做,而且比使用map和filter函數更加清晰,緣由是map和filter函數須要編寫lambda函數,下面是一例子。(固然,很複雜的一些推倒操做使用列表推倒可能會比較吃力)

上圖中列表解析法顯然清晰易懂,而採用map函數的話則要編寫兩次lambda函數,而且採用filter函數進行一次過濾操做。另外,當列表解析式變得比較複雜時,最好將推倒過程拆成兩個及以上表達式實現,總之,宗旨是使得代碼簡單易懂。


6.善於利用生成器改寫數據量較大的列表推導


在Python中,列表推導的一個毛病是:在推導的過程當中,全部被處理過的數據都會臨時存儲在內存中,舉個例子,若是你的硬盤中有一個文件,如今你要讀取這份文件並返回每一行的字符個數,那麼Python會把文件中的每一行的長度數據保存在內存中。當這個文件很大時,就會特別耗費內存。這個時候採用生成器表達式來代替列表推導,是一種很明智的選擇。建議讀者去本人另外一篇博文 【Python的迭代器和生成器】處回憶一下生成器的概念。


7.合理使用try/except/else/finnaly結構


先看一個例子:

 

不管try模塊是否發生異常,最後的finally模塊都會進行清理工做,是一種保障;

若是try塊發生了異常,則except模塊會進行異常報告;

若是try塊沒有異常,(固然except塊就不執行),else塊會接着完成程序剩下的功能;else塊縮減了try塊的代碼量,起到了分擔任務,是代碼結構清晰的做用;

各司其職。

 


 

參考:

《effective Python》,Brett Slatkin

廖雪峯的官方網站 https://www.liaoxuefeng.com

相關文章
相關標籤/搜索