1.優(yōu)化字符串格式化,替換%s,使用str.format
#優(yōu)化前寫(xiě)法
userIds = '1,2,3';
print('select * from user where id in (%s)'%(userIds))
#優(yōu)化方案一
print('select * from user where id in %(userIds)s'% {'userIds':'1,2,3'})
#推薦方案
print('select * from user where id in ({userIds})'.format(userIds='1,2,3'))
2.使用with-as-var代替try-catch-finally
with 是上線文管理器,使用with-as-var的python代碼會(huì)默認(rèn)執(zhí)行var變量class中的enter,exit兩個(gè)函數(shù)
#優(yōu)化前,常規(guī)寫(xiě)法
file = open('/data/log.txt')
data = file.read()
file.close()
#優(yōu)化推薦方案
with open('/data/log.txt') as f:
data = f.read()
3.沒(méi)有三元符,使用if-else代替;沒(méi)有switch case 使用if-else代替
#三元符號(hào)代替
x=0
y=1
print(x if x<y else y)
#switch case代替
if n==0:
print('this is n',n)
elif n==1:
print('this is n',n)
else:
print('default')
4.函數(shù)編寫(xiě)4個(gè)原則
- 函數(shù)設(shè)計(jì)要短小,嵌套層次不能過(guò)深(不要超過(guò)3層)
- 函數(shù)聲明命名合理,參數(shù)不能過(guò)多
- 函數(shù)參數(shù)設(shè)計(jì)應(yīng)該向下兼容
- 保持一個(gè)函數(shù)只干一件事情
5.數(shù)據(jù)交換值不使用中間變量
#優(yōu)化前
temp=x
x=y
y=temp
#優(yōu)化推薦方案,cool!
#主要是數(shù)值計(jì)算遇到表達(dá)式python的計(jì)算順敘導(dǎo)致
x,y=y,x
6.不使用type用來(lái)做類型判斷
- 繼承基礎(chǔ)類(int ,string等)的class使用type判斷會(huì)失敗
- python 2.2之前引入的類使用type判斷類型都是一樣的,不準(zhǔn)確
7.數(shù)值計(jì)算除法,先轉(zhuǎn)成浮點(diǎn)類后做計(jì)算(python 3已修正)
8.慎用eval。‘eval is evil’,或者使用ast.literal_eval代替
- 當(dāng)執(zhí)行字符串是用戶參數(shù),eval函數(shù)會(huì)被用來(lái)執(zhí)行用戶提交的惡意代碼
9.使用enumerate()獲取序列迭代的索引和值(字典不適用)
li = ['a','b','c','d','e','f','g','h']
#常規(guī)用法
index = 0
while index<len(li):
print('index {index},element {value}'.format(index,value=li[index]))
index=index+1
#推薦寫(xiě)法
for i,e in enumerate(li):
print('index {index},element {value}'.format(i,e)
10. is和==不相符合
- is是判斷兩個(gè)變量是同一個(gè)對(duì)象,==是指對(duì)象的值相等
11. 異常完善處理組合try-except-else-finally流程圖如下:

異常處理流程
12. None判斷空值是一個(gè)陷阱
- None既不是0,也不是False
- None是一個(gè)單例,所有賦值為None的對(duì)象都是同一個(gè)對(duì)象
#錯(cuò)誤示例
if var is not None:
do empty
else:
do some thing
#正確寫(xiě)法
#自動(dòng)調(diào)用內(nèi)部__nonzero__來(lái)判斷變量是否為空,如果一個(gè)對(duì)象沒(méi)有__nonzero__,python將會(huì)獲取__len__來(lái)判斷
#如果一個(gè)類既沒(méi)有__nonzero__,也沒(méi)有__len__,那么if的判斷都為T(mén)rue
if var :
do empty
else:
do some thing
13. 連接字符串使用join而不是+,效率高
#優(yōu)化前寫(xiě)法
#總共申請(qǐng)和復(fù)制內(nèi)存n-1次,共計(jì)n-1個(gè)中間結(jié)果
str1,str2,str3='test','string','connect'
print(str1+str2+str3)
#推薦寫(xiě)法
#處理前一次性計(jì)算申請(qǐng)內(nèi)存總數(shù),只做一次
print(''.join([str1,str2,str3]))
14. 使用Counter進(jìn)行計(jì)數(shù)統(tǒng)計(jì)
#優(yōu)化前
from collections import defaultdict
some_data = ['a','2',2,3,5,'2']
count = defaultdict(int)
for value in some_data:
count[value]+=1
#推薦優(yōu)化
from collections import Counter
print(Counter(some_data))
15. 好用的配置管理庫(kù)ConfigParser
16. 好用的命令行處理參數(shù)argparse
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-o','--output')
args = parser.parse_args()
17. 使用pandas處理大型csv文件
import pandas as pd
df = pd.read_csv('./account.csv')
#獲取文件前10行
print(df.head(n=10))
#獲取文件后10行
print(df.tail(n=10))
#獲取文件列
print(df.columns)
18. 一般情況下使用ElementTree解析XML
19. 使用traceback獲取堆棧信息
20. 使用logging記錄日志信息
- logging的名字建議按模塊命名
- logging是線程安全,但不支持多線程寫(xiě)同一個(gè)日志文件,多線程任務(wù)需要配置不同日志文件
21.使用threading模塊編寫(xiě)多線程
22.使用Queue模塊編寫(xiě)安全多線程任務(wù)
23.init不是構(gòu)造函數(shù),new才是構(gòu)造函數(shù)
24.使用Pylint檢查代碼風(fēng)格
25.利用cProfile定位性能瓶頸
#方法一,foo()為需要定位的函數(shù)
if __name__=="__main__":
import cProfile
cProfile.run("foo()")
#方法二,python解釋器調(diào)用cProfile,執(zhí)行如下命令行
python -m cProfile test.py