引用
一個程序員的微站
一,概述
Programs must be written for people to read , and only incidentally for machines to execute.
-Harold Abelson, Structure and Interpretation of Computer Programs(計算機程序的構(gòu)造和解釋)
要寫出Pythonic 優(yōu)雅的题诵,道地的洁仗,整潔的代碼,需要平時多觀察大牛代碼性锭,
Github上的requests, flask , tornado 等優(yōu)秀源代碼是學(xué)習(xí)對象赠潦,下面是一些總結(jié)的常見的pythonic寫法
一份優(yōu)雅簡潔的代碼通常自帶文檔和注釋屬性岸售,讀代碼就是讀作者的思路
python 開發(fā)中很少像Java一樣遵循某種設(shè)計模式作為開發(fā)原則中應(yīng)用于系統(tǒng)中
代碼清晰是最終目的
二锁荔,Pythonic集錦
1 變量交換
大部分編程語言交換兩個變量的值藏畅,不得不引入一個臨時變量
2 循環(huán)遍歷區(qū)間元素
xrange 返回的是生成器對象别厘,生成器比列表更加節(jié)省內(nèi)存,
需要注意xrange是python 2的寫法哩俭, python3中只有range 方法绷跑,特點和xrange一樣
3 帶有索引位置的集合遍歷
遍歷集合時候需要使用到集合的索引位置,直接對集合迭代沒有索引信息凡资,
4 字符串連接
字符串連接時候砸捏,普通的方式可以用 + 操作
join 是一種更加高效的字符串連接方式,使用+操作時候隙赁,
每執(zhí)行一次+操作在內(nèi)存中生成一個新的字符串對象垦藏,
遍歷8次有8個字符串生成,造成無謂的內(nèi)存浪費
用join 方法整個過程中只會生成一個字符串對象
5 打開/關(guān)閉 文件
執(zhí)行文件操作時候伞访,最后一定不能忘記關(guān)閉文件掂骏,即使報錯了也要close,
普通的方法是在finnally 塊中顯示的調(diào)用close()方法
使用with 語句,系統(tǒng)會在執(zhí)行玩文件操作后厚掷,自動關(guān)閉文件對象
6 列表推導(dǎo)式
能夠使用一行代碼簡明扼要的解決問題時候弟灼,不要使用兩行
與之類似的還有生成器表達式,字典推導(dǎo)式
7 善用裝飾器
裝飾器可以把與業(yè)務(wù)邏輯無關(guān)的代碼抽離出來冒黑,讓代碼保持干凈清爽田绑,
而且裝飾器還能被多個地方重復(fù)使用, 比如一個爬蟲網(wǎng)頁的函數(shù)
如果該URL曾經(jīng)被爬過就直接從緩存中獲取薛闪,否則爬下來之后加入到緩存辛馆,
防止后續(xù)重復(fù)爬取
使用裝飾器寫代碼表面上感覺代碼量更多,但是它把緩存相關(guān)的邏輯抽離出來了
可以給更多的函數(shù)調(diào)用豁延,這樣總的代碼量減少昙篙,而且業(yè)務(wù)看起來簡潔
8 合理使用列表
列表對象list 是一個查詢效率高于更新操作的數(shù)據(jù)結(jié)構(gòu),
例如刪除一個元素和插入一個元素的執(zhí)行效率非常低诱咏,因為要對剩下的元素進行移動
deque 是一個雙向隊列的數(shù)據(jù)結(jié)構(gòu)苔可,刪除元素和插入元素會很快
9 序列解包
10 遍歷字典的key 和 value
方法一速度沒有那么快,因為每一次迭代時候還要重新進行hash查找key 對應(yīng)的value
方法二遇到字典非常大的時候袋狞,會導(dǎo)致內(nèi)存的消耗增加一倍以上
iteritems 返回迭代器對象焚辅,可以節(jié)省更多的內(nèi)存,
不過在python3中沒有該方法了苟鸯,只有items方法同蜻,作用等價于iteritems
11, 鏈?zhǔn)奖容^操作
鏈?zhǔn)奖容^操作 False == False == True 等價于 False == False and False == True
所以輸出結(jié)果是False
12早处, if/else 三目運算
在類C的語言中都支持三目運算b ? x: y , Python 之禪
There should be one -- and preferably only one --obvious way to do it.
能夠使用if/else 清晰表達邏輯時候湾蔓,就沒有必要在額外新增一種方式來實現(xiàn)
13,真值判斷
檢查某個對象是否是真值砌梆, 顯示地使用True 和 False 作比較多此一舉默责,不專業(yè)
14贬循,for/else 語句
for else 是Python 特有的語法格式,else 中的代碼在for 循環(huán)遍歷完所有元素之后執(zhí)行
15桃序,字符串格式化
很難說用format 比用%s 的代碼少杖虾,但是format 更加易于理解
16,列表切片
獲取列表中的部分元素最先想到的是用for 循環(huán)根據(jù)條件提取元素媒熊,這也是其他語言中
管用的手段奇适,但是python中有強大的切片功能
列表元素的下標(biāo)不僅可以用正數(shù)表示,還可以用負數(shù)表示泛释,最后一個元素的位置是-1,
從右到左滤愕,依次遞減
17温算,善用生成器
上面是用生成器生成斐波那契數(shù)列,生成器的好處是無需一次性將所有的元素
加載到內(nèi)存怜校,只有迭代獲取元素的時候才返回元素,
而列表預(yù)先一次性把全部的元素加載到內(nèi)存注竿,
此外使用yield茄茁,代碼看起來更加簡潔
18,獲取字典元素
19巩割,預(yù)設(shè)字典默認值
通過key 分組時候裙顽,不得不每次都檢查key 是否已經(jīng)存在于字典中
20,字典推導(dǎo)式
在python2.7之前宣谈,構(gòu)建字典對象一般使用下面這種方式愈犹,可讀性非常差
字典推導(dǎo)式是python2.7新增的特性, 可讀性增強了很多闻丑,類似的還有列表推導(dǎo)式和集合推導(dǎo)式