另一方面, 絕不要描述代碼. 假設(shè)閱讀代碼的人比你更懂Python, 他只是不知道你的代碼要做什么.
# BAD COMMENT: Now go through the b array and make sure whenever i occurs# the next element is i+1類(lèi)
如果一個(gè)類(lèi)不繼承自其它類(lèi), 就顯式的從object繼承. 嵌套類(lèi)也一樣.
Yes:classSampleClass(object):passclassOuterClass(object):classInnerClass(object):passclassChildClass(ParentClass):"""Explicitly inherits from another class already."""No:classSampleClass:passclassOuterClass:classInnerClass:pass
繼承自?object?是為了使屬性(properties)正常工作, 并且這樣可以保護(hù)你的代碼, 使其不受Python 3000的一個(gè)特殊的潛在不兼容性影響. 這樣做也定義了一些特殊的方法, 這些方法實(shí)現(xiàn)了對(duì)象的默認(rèn)語(yǔ)義, 包括?__new__, __init__, __delattr__, __getattribute__, __setattr__, __hash__, __repr__, and __str__?.
字符串Yes:x=a+b x='%s, %s!'%(imperative,expletive)x='{}, {}!'.format(imperative,expletive)x='name: %s; score: %d'%(name,n)x='name: {}; score: {}'.format(name,n)No:x='%s%s'%(a,b)# use + in this casex='{}{}'.format(a,b)# use + in this casex=imperative+', '+expletive+'!'x='name: '+name+'; score: '+str(n)
避免在循環(huán)中用+和+=操作符來(lái)累加字符串. 由于字符串是不可變的, 這樣做會(huì)創(chuàng)建不必要的臨時(shí)對(duì)象, 并且導(dǎo)致二次方而不是線性的運(yùn)行時(shí)間. 作為替代方案, 你可以將每個(gè)子串加入列表, 然后在循環(huán)結(jié)束后用?.join?連接列表. (也可以將每個(gè)子串寫(xiě)入一個(gè)?cStringIO.StringIO?緩存中.)
Yes:items=['']forlast_name,first_nameinemployee_list:items.append(''%(last_name,first_name))items.append('
%s, %s |
%s, %s |
在同一個(gè)文件中, 保持使用字符串引號(hào)的一致性. 使用單引號(hào)'或者雙引號(hào)"之一用以引用字符串, 并在同一文件中沿用. 在字符串內(nèi)可以使用另外一種引號(hào), 以避免在字符串中使用. PyLint已經(jīng)加入了這一檢查.
Yes:Python('Why are you hiding your eyes?')Gollum("I'm scared of lint errors.")Narrator('"Good!" thought a happy Python reviewer.')No:Python("Why are you hiding your eyes?")Gollum('The lint. It burns. It burns us.')Gollum("Always the great lint. Watching. Watching.")
為多行字符串使用三重雙引號(hào)"""而非三重單引號(hào)'''. 當(dāng)且僅當(dāng)項(xiàng)目中使用單引號(hào)'來(lái)引用字符串時(shí), 才可能會(huì)使用三重'''為非文檔字符串的多行字符串來(lái)標(biāo)識(shí)引用. 文檔字符串必須使用三重雙引號(hào)""". 不過(guò)要注意, 通常用隱式行連接更清晰, 因?yàn)槎嘈凶址c程序其他部分的縮進(jìn)方式不一致.
Yes:print("This is much nicer.\n""Do it this way.\n")No:print"""This is pretty ugly. Don't do this. """文件和sockets
在文件和sockets結(jié)束時(shí), 顯式的關(guān)閉它.
除文件外, sockets或其他類(lèi)似文件的對(duì)象在沒(méi)有必要的情況下打開(kāi), 會(huì)有許多副作用, 例如:
它們可能會(huì)消耗有限的系統(tǒng)資源, 如文件描述符. 如果這些資源在使用后沒(méi)有及時(shí)歸還系統(tǒng), 那么用于處理這些對(duì)象的代碼會(huì)將資源消耗殆盡.
持有文件將會(huì)阻止對(duì)于文件的其他諸如移動(dòng)、刪除之類(lèi)的操作.
僅僅是從邏輯上關(guān)閉文件和sockets, 那么它們?nèi)匀豢赡軙?huì)被其共享的程序在無(wú)意中進(jìn)行讀或者寫(xiě)操作. 只有當(dāng)它們真正被關(guān)閉后, 對(duì)于它們嘗試進(jìn)行讀或者寫(xiě)操作將會(huì)跑出異常, 并使得問(wèn)題快速顯現(xiàn)出來(lái).
而且, 幻想當(dāng)文件對(duì)象析構(gòu)時(shí), 文件和sockets會(huì)自動(dòng)關(guān)閉, 試圖將文件對(duì)象的生命周期和文件的狀態(tài)綁定在一起的想法, 都是不現(xiàn)實(shí)的. 因?yàn)橛腥缦略?
沒(méi)有任何方法可以確保運(yùn)行環(huán)境會(huì)真正的執(zhí)行文件的析構(gòu). 不同的Python實(shí)現(xiàn)采用不同的內(nèi)存管理技術(shù), 比如延時(shí)垃圾處理機(jī)制. 延時(shí)垃圾處理機(jī)制可能會(huì)導(dǎo)致對(duì)象生命周期被任意無(wú)限制的延長(zhǎng).
對(duì)于文件意外的引用,會(huì)導(dǎo)致對(duì)于文件的持有時(shí)間超出預(yù)期(比如對(duì)于異常的跟蹤, 包含有全局變量等).
推薦使用??以管理文件:
withopen("hello.txt")ashello_file:forlineinhello_file:printline
對(duì)于不支持使用"with"語(yǔ)句的類(lèi)似文件的對(duì)象,使用 contextlib.closing():
importcontextlibwithcontextlib.closing(urllib.urlopen(""))asfront_page:forlineinfront_page:printline
Legacy AppEngine 中Python 2.5的代碼如使用"with"語(yǔ)句, 需要添加 "from __future__ import with_statement".
TODO注釋
為臨時(shí)代碼使用TODO注釋, 它是一種短期解決方案. 不算完美, 但夠好了.
TODO注釋?xiě)?yīng)該在所有開(kāi)頭處包含"TODO"字符串, 緊跟著是用括號(hào)括起來(lái)的你的名字, email地址或其它標(biāo)識(shí)符. 然后是一個(gè)可選的冒號(hào). 接著必須有一行注釋, 解釋要做什么. 主要目的是為了有一個(gè)統(tǒng)一的TODO格式, 這樣添加注釋的人就可以搜索到(并可以按需提供更多細(xì)節(jié)). 寫(xiě)了TODO注釋并不保證寫(xiě)的人會(huì)親自解決問(wèn)題. 當(dāng)你寫(xiě)了一個(gè)TODO, 請(qǐng)注上你的名字.
# TODO(kl@gmail.com): Use a "*" here for string repetition.# TODO(Zeke) Change this to use relations.
評(píng)論
查看更多