Python將納入高中教材,大學(xué)VB將被Python取代,現(xiàn)在你還對(duì)Python一無(wú)所知嗎?去年就被國(guó)外一機(jī)構(gòu)預(yù)測(cè),2017年python將是必學(xué)語(yǔ)言趨勢(shì),現(xiàn)在看來(lái)不假了。 背景Python 是 Google主要的腳本語(yǔ)言。這本風(fēng)格指南主要包含的是針對(duì)python的編程準(zhǔn)則。 為幫助讀者能夠?qū)⒋a準(zhǔn)確格式化,我們提供了針對(duì) Vim的配置文件 。對(duì)于Emacs用戶,保持默認(rèn)設(shè)置即可。 Python語(yǔ)言規(guī)范Lint對(duì)你的代碼運(yùn)行pylint 定義:pylint是一個(gè)在Python源代碼中查找bug的工具. 對(duì)于C和C++這樣的不那么動(dòng)態(tài)的(譯者注: 原文是less dynamic)語(yǔ)言, 這些bug通常由編譯器來(lái)捕獲. 由于Python的動(dòng)態(tài)特性, 有些警告可能不對(duì). 不過偽告警應(yīng)該很少.優(yōu)點(diǎn):可以捕獲容易忽視的錯(cuò)誤, 例如輸入錯(cuò)誤, 使用未賦值的變量等.缺點(diǎn):pylint不完美. 要利用其優(yōu)勢(shì), 我們有時(shí)侯需要: a) 圍繞著它來(lái)寫代碼 b) 抑制其告警 c) 改進(jìn)它, 或者d) 忽略它.結(jié)論:確保對(duì)你的代碼運(yùn)行pylint.抑制不準(zhǔn)確的警告,以便能夠?qū)⑵渌姹┞冻鰜?lái)。你可以通過設(shè)置一個(gè)行注釋來(lái)抑制告警. 例如: pylint警告是以一個(gè)數(shù)字編號(hào)(如 如果警告的符號(hào)名不夠見名知意,那么請(qǐng)對(duì)其增加一個(gè)詳細(xì)解釋。 采用這種抑制方式的好處是我們可以輕松查找抑制并回顧它們. 你可以使用命令 相比較于之前使用的 要抑制”參數(shù)未使用”告警, 你可以用”_”作為參數(shù)標(biāo)識(shí)符, 或者在參數(shù)名前加”unused_”. 遇到不能改變參數(shù)名的情況, 你可以通過在函數(shù)開頭”提到”它們來(lái)消除告警. 例如 導(dǎo)入僅對(duì)包和模塊使用導(dǎo)入 定義:模塊間共享代碼的重用機(jī)制.優(yōu)點(diǎn):命名空間管理約定十分簡(jiǎn)單. 每個(gè)標(biāo)識(shí)符的源都用一種一致的方式指示. x.Obj表示Obj對(duì)象定義在模塊x中.缺點(diǎn):模塊名仍可能沖突. 有些模塊名太長(zhǎng), 不太方便.結(jié)論:使用 導(dǎo)入時(shí)不要使用相對(duì)名稱. 即使模塊在同一個(gè)包中, 也要使用完整包名. 這能幫助你避免無(wú)意間導(dǎo)入一個(gè)包兩次. 包使用模塊的全路徑名來(lái)導(dǎo)入每個(gè)模塊 優(yōu)點(diǎn):避免模塊名沖突. 查找包更容易.缺點(diǎn):部署代碼變難, 因?yàn)槟惚仨殢?fù)制包層次.結(jié)論:所有的新代碼都應(yīng)該用完整包名來(lái)導(dǎo)入每個(gè)模塊.應(yīng)該像下面這樣導(dǎo)入: 異常允許使用異常, 但必須小心 定義:異常是一種跳出代碼塊的正??刂屏鱽?lái)處理錯(cuò)誤或者其它異常條件的方式.優(yōu)點(diǎn):正常操作代碼的控制流不會(huì)和錯(cuò)誤處理代碼混在一起. 當(dāng)某種條件發(fā)生時(shí), 它也允許控制流跳過多個(gè)框架. 例如, 一步跳出N個(gè)嵌套的函數(shù), 而不必繼續(xù)執(zhí)行錯(cuò)誤的代碼.缺點(diǎn):可能會(huì)導(dǎo)致讓人困惑的控制流. 調(diào)用庫(kù)時(shí)容易錯(cuò)過錯(cuò)誤情況.結(jié)論:異常必須遵守特定條件: 像這樣觸發(fā)異常: 模塊或包應(yīng)該定義自己的特定域的異?;? 這個(gè)基類應(yīng)該從內(nèi)建的Exception類繼承. 模塊的異?;悜?yīng)該叫做”Error”. 永遠(yuǎn)不要使用 使用finally子句來(lái)執(zhí)行那些無(wú)論try塊中有沒有異常都應(yīng)該被執(zhí)行的代碼. 這對(duì)于清理資源常常很有用, 例如關(guān)閉文件. 當(dāng)捕獲異常時(shí), 使用 全局變量避免全局變量 定義:定義在模塊級(jí)的變量.優(yōu)點(diǎn):偶爾有用.缺點(diǎn):導(dǎo)入時(shí)可能改變模塊行為, 因?yàn)閷?dǎo)入模塊時(shí)會(huì)對(duì)模塊級(jí)變量賦值.結(jié)論:避免使用全局變量, 用類變量來(lái)代替. 但也有一些例外:
嵌套/局部/內(nèi)部類或函數(shù)鼓勵(lì)使用嵌套/本地/內(nèi)部類或函數(shù) 定義:類可以定義在方法, 函數(shù)或者類中. 函數(shù)可以定義在方法或函數(shù)中. 封閉區(qū)間中定義的變量對(duì)嵌套函數(shù)是只讀的.優(yōu)點(diǎn):允許定義僅用于有效范圍的工具類和函數(shù).缺點(diǎn):嵌套類或局部類的實(shí)例不能序列化(pickled).結(jié)論:推薦使用. 列表推導(dǎo)(List Comprehensions)可以在簡(jiǎn)單情況下使用 定義:列表推導(dǎo)(list comprehensions)與生成器表達(dá)式(generator expression)提供了一種簡(jiǎn)潔高效的方式來(lái)創(chuàng)建列表和迭代器, 而不必借助map(), filter(), 或者lambda.優(yōu)點(diǎn):簡(jiǎn)單的列表推導(dǎo)可以比其它的列表創(chuàng)建方法更加清晰簡(jiǎn)單. 生成器表達(dá)式可以十分高效, 因?yàn)樗鼈儽苊饬藙?chuàng)建整個(gè)列表.缺點(diǎn):復(fù)雜的列表推導(dǎo)或者生成器表達(dá)式可能難以閱讀.結(jié)論:適用于簡(jiǎn)單情況. 每個(gè)部分應(yīng)該單獨(dú)置于一行: 映射表達(dá)式, for語(yǔ)句, 過濾器表達(dá)式. 禁止多重for語(yǔ)句或過濾器表達(dá)式. 復(fù)雜情況下還是使用循環(huán). 默認(rèn)迭代器和操作符如果類型支持, 就使用默認(rèn)迭代器和操作符. 比如列表, 字典及文件等. 定義:容器類型, 像字典和列表, 定義了默認(rèn)的迭代器和關(guān)系測(cè)試操作符(in和not in)優(yōu)點(diǎn):默認(rèn)操作符和迭代器簡(jiǎn)單高效, 它們直接表達(dá)了操作, 沒有額外的方法調(diào)用. 使用默認(rèn)操作符的函數(shù)是通用的. 它可以用于支持該操作的任何類型.缺點(diǎn):你沒法通過閱讀方法名來(lái)區(qū)分對(duì)象的類型(例如, has_key()意味著字典). 不過這也是優(yōu)點(diǎn).結(jié)論:如果類型支持, 就使用默認(rèn)迭代器和操作符, 例如列表, 字典和文件. 內(nèi)建類型也定義了迭代器方法. 優(yōu)先考慮這些方法, 而不是那些返回列表的方法. 當(dāng)然,這樣遍歷容器時(shí),你將不能修改容器. 生成器按需使用生成器. 定義:所謂生成器函數(shù), 就是每當(dāng)它執(zhí)行一次生成(yield)語(yǔ)句, 它就返回一個(gè)迭代器, 這個(gè)迭代器生成一個(gè)值. 生成值后, 生成器函數(shù)的運(yùn)行狀態(tài)將被掛起, 直到下一次生成.優(yōu)點(diǎn):簡(jiǎn)化代碼, 因?yàn)槊看握{(diào)用時(shí), 局部變量和控制流的狀態(tài)都會(huì)被保存. 比起一次創(chuàng)建一系列值的函數(shù), 生成器使用的內(nèi)存更少.缺點(diǎn):沒有.結(jié)論:鼓勵(lì)使用. 注意在生成器函數(shù)的文檔字符串中使用”Yields:”而不是”Returns:”.(譯者注: 參看 注釋 ) Lambda函數(shù)適用于單行函數(shù) 定義:與語(yǔ)句相反, lambda在一個(gè)表達(dá)式中定義匿名函數(shù). 常用于為 條件表達(dá)式適用于單行函數(shù) 定義:條件表達(dá)式是對(duì)于if語(yǔ)句的一種更為簡(jiǎn)短的句法規(guī)則. 例如: 默認(rèn)參數(shù)值適用于大部分情況. 定義:你可以在函數(shù)參數(shù)列表的最后指定變量的值, 例如, 屬性(properties)訪問和設(shè)置數(shù)據(jù)成員時(shí), 你通常會(huì)使用簡(jiǎn)單, 輕量級(jí)的訪問和設(shè)置函數(shù). 建議用屬性(properties)來(lái)代替它們. 定義:一種用于包裝方法調(diào)用的方式. 當(dāng)運(yùn)算量不大, 它是獲取和設(shè)置屬性(attribute)的標(biāo)準(zhǔn)方式.優(yōu)點(diǎn):通過消除簡(jiǎn)單的屬性(attribute)訪問時(shí)顯式的get和set方法調(diào)用, 可讀性提高了. 允許懶惰的計(jì)算. 用Pythonic的方式來(lái)維護(hù)類的接口. 就性能而言, 當(dāng)直接訪問變量是合理的, 添加訪問方法就顯得瑣碎而無(wú)意義. 使用屬性(properties)可以繞過這個(gè)問題. 將來(lái)也可以在不破壞接口的情況下將訪問方法加上.缺點(diǎn):屬性(properties)是在get和set方法聲明后指定, 這需要使用者在接下來(lái)的代碼中注意: set和get是用于屬性(properties)的(除了用 (譯者注: 老實(shí)說(shuō), 我覺得這段示例代碼很不恰當(dāng), 有必要這么蛋疼嗎?) True/False的求值盡可能使用隱式false 定義:Python在布爾上下文中會(huì)將某些值求值為false. 按簡(jiǎn)單的直覺來(lái)講, 就是所有的”空”值都被認(rèn)為是false. 因此0, None, [], {}, “” 都被認(rèn)為是false.優(yōu)點(diǎn):使用Python布爾值的條件語(yǔ)句更易讀也更不易犯錯(cuò). 大部分情況下, 也更快.缺點(diǎn):對(duì)C/C++開發(fā)人員來(lái)說(shuō), 可能看起來(lái)有點(diǎn)怪.結(jié)論:盡可能使用隱式的false, 例如: 使用
過時(shí)的語(yǔ)言特性盡可能使用字符串方法取代字符串模塊. 使用函數(shù)調(diào)用語(yǔ)法取代apply(). 使用列表推導(dǎo), for循環(huán)取代filter(), map()以及reduce(). 定義:當(dāng)前版本的Python提供了大家通常更喜歡的替代品.結(jié)論:我們不使用不支持這些特性的Python版本, 所以沒理由不用新的方式. 詞法作用域(Lexical Scoping)推薦使用 定義:嵌套的Python函數(shù)可以引用外層函數(shù)中定義的變量, 但是不能夠?qū)λ鼈冑x值. 變量綁定的解析是使用詞法作用域, 也就是基于靜態(tài)的程序文本. 對(duì)一個(gè)塊中的某個(gè)名稱的任何賦值都會(huì)導(dǎo)致Python將對(duì)該名稱的全部引用當(dāng)做局部變量, 甚至是賦值前的處理. 如果碰到global聲明, 該名稱就會(huì)被視作全局變量.一個(gè)使用這個(gè)特性的例子: (譯者注: 這個(gè)例子有點(diǎn)詭異, 你應(yīng)該這樣使用這個(gè)函數(shù): 優(yōu)點(diǎn):通??梢詭?lái)更加清晰, 優(yōu)雅的代碼. 尤其會(huì)讓有經(jīng)驗(yàn)的Lisp和Scheme(還有Haskell, ML等)程序員感到欣慰.缺點(diǎn):可能導(dǎo)致讓人迷惑的bug. 例如下面這個(gè)依據(jù) PEP-0227 的例子: 因此 (譯者注: x是一個(gè)列表, for循環(huán)其實(shí)是將x中的值依次賦給i.這樣對(duì)i的賦值就隱式的發(fā)生了, 整個(gè)foo函數(shù)體中的i都會(huì)被當(dāng)做局部變量, 包括bar()中的那個(gè). 這一點(diǎn)與C++之類的靜態(tài)語(yǔ)言還是有很大差別的.) 結(jié)論:鼓勵(lì)使用. 函數(shù)與方法裝飾器如果好處很顯然, 就明智而謹(jǐn)慎的使用裝飾器 定義:用于函數(shù)及方法的裝飾器 (也就是@標(biāo)記). 最常見的裝飾器是@classmethod 和@staticmethod, 用于將常規(guī)函數(shù)轉(zhuǎn)換成類方法或靜態(tài)方法. 不過, 裝飾器語(yǔ)法也允許用戶自定義裝飾器. 特別地, 對(duì)于某個(gè)函數(shù)
線程不要依賴內(nèi)建類型的原子性. 雖然Python的內(nèi)建類型例如字典看上去擁有原子操作, 但是在某些情形下它們?nèi)匀徊皇窃拥?即: 如果__hash__或__eq__被實(shí)現(xiàn)為Python方法)且它們的原子性是靠不住的. 你也不能指望原子變量賦值(因?yàn)檫@個(gè)反過來(lái)依賴字典). 優(yōu)先使用Queue模塊的 威力過大的特性避免使用這些特性 定義:Python是一種異常靈活的語(yǔ)言, 它為你提供了很多花哨的特性, 諸如元類(metaclasses), 字節(jié)碼訪問, 任意編譯(on-the-fly compilation), 動(dòng)態(tài)繼承, 對(duì)象父類重定義(object reparenting), 導(dǎo)入黑客(import hacks), 反射, 系統(tǒng)內(nèi)修改(modification of system internals), 等等.優(yōu)點(diǎn):強(qiáng)大的語(yǔ)言特性, 能讓你的代碼更緊湊.缺點(diǎn):使用這些很”酷”的特性十分誘人, 但不是絕對(duì)必要. 使用奇技淫巧的代碼將更加難以閱讀和調(diào)試. 開始可能還好(對(duì)原作者而言), 但當(dāng)你回顧代碼, 它們可能會(huì)比那些稍長(zhǎng)一點(diǎn)但是很直接的代碼更加難以理解.結(jié)論:在你的代碼中避免這些特性. Python風(fēng)格規(guī)范分號(hào)不要在行尾加分號(hào), 也不要用分號(hào)將兩條命令放在同一行. 行長(zhǎng)度每行不超過80個(gè)字符 例外:
不要使用反斜杠連接行. Python會(huì)將 圓括號(hào), 中括號(hào)和花括號(hào)中的行隱式的連接起來(lái) , 你可以利用這個(gè)特點(diǎn). 如果需要, 你可以在表達(dá)式外圍增加一對(duì)額外的圓括號(hào). 如果一個(gè)文本字符串在一行放不下, 可以使用圓括號(hào)來(lái)實(shí)現(xiàn)隱式行連接: 在注釋中,如果必要,將長(zhǎng)的URL放在一行上。 注意上面例子中的元素縮進(jìn); 你可以在本文的 縮進(jìn) 部分找到解釋. 括號(hào)寧缺毋濫的使用括號(hào) 除非是用于實(shí)現(xiàn)行連接, 否則不要在返回語(yǔ)句或條件語(yǔ)句中使用括號(hào). 不過在元組兩邊使用括號(hào)是可以的. 縮進(jìn)用4個(gè)空格來(lái)縮進(jìn)代碼 絕對(duì)不要用tab, 也不要tab和空格混用. 對(duì)于行連接的情況, 你應(yīng)該要么垂直對(duì)齊換行的元素(見 行長(zhǎng)度 部分的示例), 或者使用4空格的懸掛式縮進(jìn)(這時(shí)第一行不應(yīng)該有參數(shù)): 空行頂級(jí)定義之間空兩行, 方法定義之間空一行 頂級(jí)定義之間空兩行, 比如函數(shù)或者類定義. 方法定義, 類定義與第一個(gè)方法之間, 都應(yīng)該空一行. 函數(shù)或方法中, 某些地方要是你覺得合適, 就空一行. 空格按照標(biāo)準(zhǔn)的排版規(guī)范來(lái)使用標(biāo)點(diǎn)兩邊的空格 括號(hào)內(nèi)不要有空格. 不要在逗號(hào), 分號(hào), 冒號(hào)前面加空格, 但應(yīng)該在它們后面加(除了在行尾). 參數(shù)列表, 索引或切片的左括號(hào)前不應(yīng)加空格. 在二元操作符兩邊都加上一個(gè)空格, 比如賦值(=), 比較(==, <,>, !=, <>, <=,>=, in, not in, is, is not), 布爾(and, or, not). 至于算術(shù)操作符兩邊的空格該如何使用, 需要你自己好好判斷. 不過兩側(cè)務(wù)必要保持一致. 當(dāng)’=’用于指示關(guān)鍵字參數(shù)或默認(rèn)參數(shù)值時(shí), 不要在其兩側(cè)使用空格. 不要用空格來(lái)垂直對(duì)齊多行間的標(biāo)記, 因?yàn)檫@會(huì)成為維護(hù)的負(fù)擔(dān)(適用于:, #, =等): Shebang大部分.py文件不必以#!作為文件的開始. 根據(jù) PEP-394 , 程序的main文件應(yīng)該以 #!/usr/bin/python2或者 #!/usr/bin/python3開始. (譯者注: 在計(jì)算機(jī)科學(xué)中, Shebang (也稱為Hashbang)是一個(gè)由井號(hào)和嘆號(hào)構(gòu)成的字符串行(#!), 其出現(xiàn)在文本文件的第一行的前兩個(gè)字符. 在文件中存在Shebang的情況下, 類Unix操作系統(tǒng)的程序載入器會(huì)分析Shebang后的內(nèi)容, 將這些內(nèi)容作為解釋器指令, 并調(diào)用該指令, 并將載有Shebang的文件路徑作為該解釋器的參數(shù). 例如, 以指令#!/bin/sh開頭的文件在執(zhí)行時(shí)會(huì)實(shí)際調(diào)用/bin/sh程序.) #!先用于幫助內(nèi)核找到Python解釋器, 但是在導(dǎo)入模塊時(shí), 將會(huì)被忽略. 因此只有被直接執(zhí)行的文件中才有必要加入#!. 注釋確保對(duì)模塊, 函數(shù), 方法和行內(nèi)注釋使用正確的風(fēng)格 文檔字符串
模塊
函數(shù)和方法 下文所指的函數(shù),包括函數(shù), 方法, 以及生成器. 一個(gè)函數(shù)必須要有文檔字符串, 除非它滿足以下條件:
文檔字符串應(yīng)該包含函數(shù)做什么, 以及輸入和輸出的詳細(xì)描述. 通常, 不應(yīng)該描述”怎么做”, 除非是一些復(fù)雜的算法. 文檔字符串應(yīng)該提供足夠的信息, 當(dāng)別人編寫代碼調(diào)用該函數(shù)時(shí), 他不需要看一行代碼, 只要看文檔字符串就可以了. 對(duì)于復(fù)雜的代碼, 在代碼旁邊加注釋會(huì)比使用文檔字符串更有意義. 關(guān)于函數(shù)的幾個(gè)方面應(yīng)該在特定的小節(jié)中進(jìn)行描述記錄, 這幾個(gè)方面如下文所述. 每節(jié)應(yīng)該以一個(gè)標(biāo)題行開始. 標(biāo)題行以冒號(hào)結(jié)尾. 除標(biāo)題行外, 節(jié)的其他內(nèi)容應(yīng)被縮進(jìn)2個(gè)空格. Args:列出每個(gè)參數(shù)的名字, 并在名字后使用一個(gè)冒號(hào)和一個(gè)空格, 分隔對(duì)該參數(shù)的描述.如果描述太長(zhǎng)超過了單行80字符,使用2或者4個(gè)空格的懸掛縮進(jìn)(與文件其他部分保持一致). 描述應(yīng)該包括所需的類型和含義. 如果一個(gè)函數(shù)接受*foo(可變長(zhǎng)度參數(shù)列表)或者**bar (任意關(guān)鍵字參數(shù)), 應(yīng)該詳細(xì)列出*foo和**bar.Returns: (或者 Yields: 用于生成器)描述返回值的類型和語(yǔ)義. 如果函數(shù)返回None, 這一部分可以省略.Raises:列出與接口有關(guān)的所有異常. 類 類應(yīng)該在其定義下有一個(gè)用于描述該類的文檔字符串. 如果你的類有公共屬性(Attributes), 那么文檔中應(yīng)該有一個(gè)屬性(Attributes)段. 并且應(yīng)該遵守和函數(shù)參數(shù)相同的格式. 塊注釋和行注釋 最需要寫注釋的是代碼中那些技巧性的部分. 如果你在下次 代碼審查 的時(shí)候必須解釋一下, 那么你應(yīng)該現(xiàn)在就給它寫注釋. 對(duì)于復(fù)雜的操作, 應(yīng)該在其操作開始前寫上若干行注釋. 對(duì)于不是一目了然的代碼, 應(yīng)在其行尾添加注釋. 為了提高可讀性, 注釋應(yīng)該至少離開代碼2個(gè)空格. 另一方面, 絕不要描述代碼. 假設(shè)閱讀代碼的人比你更懂Python, 他只是不知道你的代碼要做什么. 類如果一個(gè)類不繼承自其它類, 就顯式的從object繼承. 嵌套類也一樣. 繼承自 字符串即使參數(shù)都是字符串, 使用%操作符或者格式化方法格式化字符串. 不過也不能一概而論, 你需要在+和%之間好好判定. 避免在循環(huán)中用+和+=操作符來(lái)累加字符串. 由于字符串是不可變的, 這樣做會(huì)創(chuàng)建不必要的臨時(shí)對(duì)象, 并且導(dǎo)致二次方而不是線性的運(yùn)行時(shí)間. 作為替代方案, 你可以將每個(gè)子串加入列表, 然后在循環(huán)結(jié)束后用 在同一個(gè)文件中, 保持使用字符串引號(hào)的一致性. 使用單引號(hào)’或者雙引號(hào)”之一用以引用字符串, 并在同一文件中沿用. 在字符串內(nèi)可以使用另外一種引號(hào), 以避免在字符串中使用. GPyLint已經(jīng)加入了這一檢查. (譯者注:GPyLint疑為筆誤, 應(yīng)為PyLint.) 為多行字符串使用三重雙引號(hào)”“”而非三重單引號(hào)’‘’. 當(dāng)且僅當(dāng)項(xiàng)目中使用單引號(hào)’來(lái)引用字符串時(shí), 才可能會(huì)使用三重’‘’為非文檔字符串的多行字符串來(lái)標(biāo)識(shí)引用. 文檔字符串必須使用三重雙引號(hào)”“”. 不過要注意, 通常用隱式行連接更清晰, 因?yàn)槎嘈凶址c程序其他部分的縮進(jìn)方式不一致. 文件和sockets在文件和sockets結(jié)束時(shí), 顯式的關(guān)閉它. 除文件外, sockets或其他類似文件的對(duì)象在沒有必要的情況下打開, 會(huì)有許多副作用, 例如:
而且, 幻想當(dāng)文件對(duì)象析構(gòu)時(shí), 文件和sockets會(huì)自動(dòng)關(guān)閉, 試圖將文件對(duì)象的生命周期和文件的狀態(tài)綁定在一起的想法, 都是不現(xiàn)實(shí)的. 因?yàn)橛腥缦略?
推薦使用 “with”語(yǔ)句 以管理文件: 對(duì)于不支持使用”with”語(yǔ)句的類似文件的對(duì)象,使用 contextlib.closing(): Legacy AppEngine 中Python 2.5的代碼如使用”with”語(yǔ)句, 需要添加 “from __future__ import with_statement”. TODO注釋為臨時(shí)代碼使用TODO注釋, 它是一種短期解決方案. 不算完美, 但夠好了. TODO注釋應(yīng)該在所有開頭處包含”TODO”字符串, 緊跟著是用括號(hào)括起來(lái)的你的名字, email地址或其它標(biāo)識(shí)符. 然后是一個(gè)可選的冒號(hào). 接著必須有一行注釋, 解釋要做什么. 主要目的是為了有一個(gè)統(tǒng)一的TODO格式, 這樣添加注釋的人就可以搜索到(并可以按需提供更多細(xì)節(jié)). 寫了TODO注釋并不保證寫的人會(huì)親自解決問題. 當(dāng)你寫了一個(gè)TODO, 請(qǐng)注上你的名字. 如果你的TODO是”將來(lái)做某事”的形式, 那么請(qǐng)確保你包含了一個(gè)指定的日期(“2009年11月解決”)或者一個(gè)特定的事件(“等到所有的客戶都可以處理XML請(qǐng)求就移除這些代碼”). 導(dǎo)入格式每個(gè)導(dǎo)入應(yīng)該獨(dú)占一行 導(dǎo)入總應(yīng)該放在文件頂部, 位于模塊注釋和文檔字符串之后, 模塊全局變量和常量之前. 導(dǎo)入應(yīng)該按照從最通用到最不通用的順序分組:
每種分組中, 應(yīng)該根據(jù)每個(gè)模塊的完整包路徑按字典序排序, 忽略大小寫. 語(yǔ)句通常每個(gè)語(yǔ)句應(yīng)該獨(dú)占一行 不過, 如果測(cè)試結(jié)果與測(cè)試語(yǔ)句在一行放得下, 你也可以將它們放在同一行. 如果是if語(yǔ)句, 只有在沒有else時(shí)才能這樣做. 特別地, 絕不要對(duì) 訪問控制在Python中, 對(duì)于瑣碎又不太重要的訪問函數(shù), 你應(yīng)該直接使用公有變量來(lái)取代它們, 這樣可以避免額外的函數(shù)調(diào)用開銷. 當(dāng)添加更多功能時(shí), 你可以用屬性(property)來(lái)保持語(yǔ)法的一致性. (譯者注: 重視封裝的面向?qū)ο蟪绦騿T看到這個(gè)可能會(huì)很反感, 因?yàn)樗麄円恢北唤逃? 所有成員變量都必須是私有的! 其實(shí), 那真的是有點(diǎn)麻煩啊. 試著去接受Pythonic哲學(xué)吧) 另一方面, 如果訪問更復(fù)雜, 或者變量的訪問開銷很顯著, 那么你應(yīng)該使用像 命名module_name, package_name, ClassName, method_name, ExceptionName, function_name, GLOBAL_VAR_NAME, instance_var_name, function_parameter_name, local_var_name. 應(yīng)該避免的名稱
命名約定
Python之父Guido推薦的規(guī)范 Main即使是一個(gè)打算被用作腳本的文件, 也應(yīng)該是可導(dǎo)入的. 并且簡(jiǎn)單的導(dǎo)入不應(yīng)該導(dǎo)致這個(gè)腳本的主功能(main functionality)被執(zhí)行, 這是一種副作用. 主功能應(yīng)該放在一個(gè)main()函數(shù)中. 在Python中, pydoc以及單元測(cè)試要求模塊必須是可導(dǎo)入的. 你的代碼應(yīng)該在執(zhí)行主程序前總是檢查 所有的頂級(jí)代碼在模塊導(dǎo)入時(shí)都會(huì)被執(zhí)行. 要小心不要去調(diào)用函數(shù), 創(chuàng)建對(duì)象, 或者執(zhí)行那些不應(yīng)該在使用pydoc時(shí)執(zhí)行的操作. =,>,> |
|