譯者對(duì)原文中有些地方可能理解的不對(duì)目代,如果有朋友發(fā)現(xiàn)錯(cuò)誤笛洛,希望可以告訴我巡蘸,謝謝!
原文地址:Github Gist
譯文地址:編程派
總體原則
價(jià)值
- “為別人開發(fā)你也想要使用的工具饵骨。” ——Kenneth Reitz
- "簡(jiǎn)潔總是勝過(guò)可用茫打。" ——Pieter Hintjens
- "滿足90%的使用場(chǎng)景居触。忽略那些說(shuō)不的人。" ——Kenneth Reitz
- "優(yōu)美勝過(guò)丑陋老赤。" ——PEP 20
- 為開源(甚至是閉源項(xiàng)目)而開發(fā)轮洋。
一般開發(fā)準(zhǔn)則
- “明確勝過(guò)含蓄√” —— PEP 20
- “易讀亦有價(jià)弊予。” —— PEP 20
- “人人都能打補(bǔ)丁开财『浩猓” —— 可汗學(xué)院開發(fā)文檔
- 一旦發(fā)現(xiàn)破窗(設(shè)計(jì)錯(cuò)誤,決策失誤或編碼質(zhì)量低)责鳍,馬上修補(bǔ)碾褂。
- “現(xiàn)在做也要?jiǎng)龠^(guò)不去做∞备椋” —— PEP 20
- "測(cè)試要徹底斋扰。撰寫新功能文檔。"
- 人力驅(qū)動(dòng)型開發(fā),比測(cè)試驅(qū)動(dòng)型開發(fā)更重要传货。(譯者:原文為Even more important that Test-Driven Development--Human-Driven Development屎鳍,譯者認(rèn)為more important that應(yīng)該是more important than,應(yīng)該是作者筆誤问裕,否則意思不通逮壁,)
- 這些準(zhǔn)則可能——應(yīng)該是很可能——會(huì)改變。
特殊準(zhǔn)則
風(fēng)格
感覺合理的話粮宛,就遵循PEP 8窥淆。
命名
- 變量、函數(shù)巍杈、方法忧饭、包、模塊
- 小寫筷畦,并使用下劃線分隔單詞(lower_case_with_underscores)
- 類词裤、異常
- 首字母大寫(CapWords)
- 受保護(hù)的方法和內(nèi)部函數(shù)
- 單下劃線開頭(_single_leading_underscore(self, ...))
- 私有的方法
- 雙下劃線開頭(__double_leading_underscore(self, ...))
- 常量
- 字母全部大寫,單詞間用下劃線分隔(ALL_CAPS_WITH_UNDERSCORES)
一般命名準(zhǔn)則
盡量不要使用只有一個(gè)字母的變量名(例如鳖宾,l吼砂,I,O等)鼎文。
例外:在很簡(jiǎn)短的代碼塊中渔肩,如果變量名的意思可以從上下文明顯地看出來(lái),即可拇惋。
沒(méi)問(wèn)題
for e in elements:
e.mutate()
避免重復(fù)變量名周偎。
正確的做法
import audio
core = audio.Core()
controller = audio.Controller()
錯(cuò)誤的做法
import audio
core = audio.AudioCore()
controller = audio.AudioController()
“反向標(biāo)記”更好。
正確的做法
elements = ...
elements_active = ...
elements_defunct = ...
錯(cuò)誤的做法
elements = ...
active_elements = ...
defunct_elements ...
避免使用getter和setter方法蚤假。
正確的做法
person.age = 42
錯(cuò)誤的做法
person.set_age(42)
縮進(jìn)
用4個(gè)空格符——永遠(yuǎn)別用Tab制表符栏饮。就說(shuō)這么多。
模塊引用
引用整個(gè)模塊磷仰,而不是模塊中的單個(gè)標(biāo)識(shí)符袍嬉。舉個(gè)例子,假設(shè)一個(gè)cantee模塊下面灶平,有一個(gè)sessions.py文件伺通,
正確的做法
import canteen
import canteen.sessions
from canteen import sessions
錯(cuò)誤的做法
from canteen import get_user # Symbol from canteen/__init__.py
from canteen.sessions import get_session # Symbol from canteen/sessions.py
例外:如果第三方代碼的文檔中明確說(shuō)明要單個(gè)引用,即可逢享。
理由:避免循環(huán)引用罐监。看這里瞒爬。
把代碼引用部分放在文件的頂部弓柱,按下面的順序分成三個(gè)部分沟堡,每個(gè)部分之間空一行。
- 系統(tǒng)引用
- 第三方引用
- 本地引用
理由:明確顯示每個(gè)模塊的引用來(lái)源矢空。
文檔
遵循PEP 257提出的文檔字符串準(zhǔn)則航罗。reStructuredText (reST) 和Sphinx有助于確保文檔符合標(biāo)準(zhǔn)。
對(duì)于功能明顯的函數(shù)屁药,撰寫一行文檔字符串粥血。
"""返回``foo``的路徑名."""
多行文檔字符串應(yīng)包括:
一行摘要
合適的話,請(qǐng)描述使用場(chǎng)景
參數(shù)
-
返回?cái)?shù)據(jù)類型和語(yǔ)義信息酿箭,除非返回
None
"""訓(xùn)練一個(gè)用來(lái)區(qū)分Foo和Bar的模型复亏。
用法::
>>> import klassify >>> data = [("green", "foo"), ("orange", "bar")] >>> classifier = klassify.train(data)
:param train_data:
(color, label)
形式的一個(gè)元祖列表。:rtype: A :class:
Classifier <Classifier>
"""
注意
使用主動(dòng)詞(“返回”)缭嫡,而不是描述性的單詞(“返回值”)缔御。
在類的文檔字符串中為__init__
方法撰寫文檔。
class Person(object):
"""A simple representation of a human being.
:param name: A string, the person's name.
:param age: An int, the person's age.
"""
def __init__(self, name, age):
self.name = name
self.age = age
關(guān)于注釋
盡量少用械巡。與其寫很多注釋刹淌,不如提高代碼可讀性。通常情況下讥耗,短小的方法比注釋更有效。
錯(cuò)誤的做法
# If the sign is a stop sign
if sign.color == 'red' and sign.sides == 8:
stop()
正確的做法
def is_stop_sign(sign):
return sign.color == 'red' and sign.sides == 8
if is_stop_sign(sign):
stop()
但是的確要寫注釋時(shí)疹启,請(qǐng)牢記:“遵循斯托克與懷特所寫的《風(fēng)格的要素》古程。” —— PEP 8
每行的長(zhǎng)度
不要過(guò)分在意喊崖。80到100個(gè)字符都是沒(méi)問(wèn)題的挣磨。
使用括號(hào)延續(xù)當(dāng)前行。
wiki = (
"The Colt Python is a .357 Magnum caliber revolver formerly manufactured "
"by Colt's Manufacturing Company of Hartford, Connecticut. It is sometimes "
'referred to as a "Combat Magnum". It was first introduced in 1955, the '
"same year as Smith & Wesson's M29 .44 Magnum."
)
測(cè)試
盡量爭(zhēng)取測(cè)試全部代碼荤懂,但也不必執(zhí)著于覆蓋率茁裙。
一般測(cè)試準(zhǔn)則
- 使用較長(zhǎng)的、描述性的名稱节仿。通常情況下晤锥,這能避免在測(cè)試方法中再寫文檔。
- 測(cè)試之間應(yīng)該是孤立的廊宪。不要與真實(shí)地?cái)?shù)據(jù)庫(kù)或網(wǎng)絡(luò)進(jìn)行交互矾瘾。使用單獨(dú)的測(cè)試數(shù)據(jù)庫(kù),測(cè)試完即可銷毀箭启,或者是使用模擬對(duì)象壕翩。
- 使用工廠模式,而不是fixture傅寡。
- 別讓不完整的測(cè)試通過(guò)放妈,否則你就有可能忘記北救。你應(yīng)該加上一些占位語(yǔ)句,比如
assert False, "TODO: finish me"
芜抒。
單元測(cè)試
每次聚焦一個(gè)很小的功能點(diǎn)扭倾。
運(yùn)行速度要快,但是速度慢總比不測(cè)試好挽绩。
-
通常膛壹,每一個(gè)類或模型都應(yīng)該有一個(gè)測(cè)試用例類。
import unittest
import factoriesclass PersonTest(unittest.TestCase):
def setUp(self):
self.person = factories.PersonFactory()def test_has_age_in_dog_years(self): self.assertEqual(self.person.dog_years, self.person.age / 7)
功能測(cè)試
功能測(cè)試是更高層次的測(cè)試唉堪,更接近最終用戶如何與應(yīng)用交互這一層面模聋。通常用在網(wǎng)絡(luò)應(yīng)用與圖形應(yīng)用測(cè)試。
按照?qǐng)鼍白珜憸y(cè)試唠亚。測(cè)試用例的測(cè)試方法命名應(yīng)該看上去像場(chǎng)景描述链方。
-
在編寫代碼之前,通過(guò)注釋說(shuō)明具體場(chǎng)景信息灶搜。
import unittest
class TestAUser(unittest.TestCase):
def test_can_write_a_blog_post(self): # Goes to the her dashboard ... # Clicks "New Post" ... # Fills out the post form ... # Clicks "Submit" ... # Can see the new post ...
請(qǐng)注意祟蚀,測(cè)試用例的類名稱和測(cè)試方法的名稱放在一起,就像是“測(cè)試一名用戶能否發(fā)布博文”割卖。