編寫(xiě)高質(zhì)量python代碼

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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容