PEP8中文版 -- Python編碼風格指南

Python部落組織翻譯, 禁止轉載python

目錄
      縮進
      製表符仍是空格?
      行的最大長度
      空行
      源文件編碼
      導入
      沒法忍受的
      其它建議
      註釋塊
      行內註釋
      文檔字符串
      根本原則
      描述:命名風格
      規定:命名約定程序員

 

算法

 

本文檔所提供的編碼規範,適用於主要的Python發行版中組成標準庫的Python代碼。請參閱PEP關於Python的C實現的C編碼風格指南的描述[1]。

本文檔和PEP257(文檔字符串規範)改編自Guido的《Python Style Guide》一文,用Barry的風格指南[2]作一些補充。

這篇風格指南隨着時間的推移而逐漸演變,隨着語言自己的變化,過去的約定已通過時了並肯定了更多新的約定。

許多項目都有本身的編碼風格指南。若是有任何衝突,優先使用該項目特定的指南。編程

 

使人討厭的小人物身上愚蠢的一致性緩存

 

Guido的一個重要的看法是,代碼閱讀的次數比編寫的次數多。這裏提供的指南旨在提升代碼的可讀性,並使各類不一樣的Python代碼一致。如PEP20所說,「易讀性很是重要」。

風格指南是關於一致性的。與本風格指南一致很重要。項目中的一致性更重要。一個模塊或功能中的一致性最重要。

最重要的是:知道什麼時候會不一致——有時風格指南就不適用了。懷疑時,做出你最佳的判斷。看看其餘的例子,並決定什麼是最好的。不要猶豫,儘管發問!

特別地:不要只爲聽從這個PEP而打破向後兼容性!

忽視既定指南的一些其餘的好理由:
一、當應用指南會下降代碼的可讀性,即便對於那些習慣遵守這個PEP來閱讀代碼的人來講。
二、與周圍的代碼保持一致也會破壞它(多是歷史緣由)——雖然這也是收拾別人爛攤子的好機會(在真正的XP風格中)。
三、由於問題代碼先於指南,又沒有其它的修改理由。
四、代碼須要兼容老版本,本風格指南不建議使用的Python特性。網絡

 

代碼佈局數據結構

 

縮進框架

 

每級縮進使用4個空格。
連續行應該對齊摺疊元素,不管是垂直的Python的隱式行鏈接圓括號內的,中括號內的,大括號內的,仍是使用懸掛縮進[5]。使用懸掛縮進應注意如下幾點;socket

 

第一行沒有參數而且使用更多的縮進來區別它自己和連續行。編輯器

 

風格良好:

article4.png


風格不良:

article4.png


對於連續行,4個空格規則是可選的。
可選的:
article4.png


if語句條件塊足夠長時須要編寫多行,值得注意的是兩個字符組成的關鍵字(例如if),加上一個空格,加上開括號爲多行條件的後續行建立一個4個空格的縮進。這能夠給嵌入if內的縮進語句產生視覺衝突,這也天然被縮進4個空格。這個PEP沒有明確如何(是否)進一步區分條件行和if語句內的嵌入行。這種狀況下,能夠接受的選項包括,但不只限於:

article4.png


多行結構中的結束花括號/中括號/圓括號是最後一行的第一個非空白字符,如:

article4.png

或者是最後一行的第一個字符,如:

article4.png

 

製表符仍是空格?

 

空格是縮進方法的首選。
製表符僅用於與已經用製表符作縮進的代碼保持一致。
Python3不容許混用製表符和空格來縮進。
Python2代碼混用製表符和空格縮進,將被轉化爲只使用空格。
調用Python2命令行解釋器時使用-t選項,可對代碼中非法混用製表符和空格發出警告。當使用-tt選項,警告將變成錯誤。這些選項是高度推薦的!

 

行的最大長度


限制全部行最多79個字符。

下垂的長塊結構限制爲更少的文本(文檔字符串或註釋),行的長度應該限制在72個字符。

限制編輯器窗口寬度使得並排打開多個文件成爲可能,而且使用代碼審查工具顯示相鄰列的兩個版本工做正常。

絕大多數工具的默認摺疊會破壞代碼的可視化結構,使其更難以理解。編輯器中的窗口寬度設置爲80個字符。即便該工具將在最後一列中標記字形。一些基於網絡的工具可能不會提供動態的自動換行。

有些團隊強烈喜歡較長的行長度。對於代碼維護徹底或主要由一個團隊的,能夠在這個問題上達成協議,象徵性的將行長度從80個字符增長到100個字符(有效地增長最大長度到99個字符)也是能夠的,提供註釋和文檔字符串還是72個字符。

Python標準庫採起保守作法,要求行限制到79個字符(文檔字符串/註釋到72個字符)。

摺疊長行的首選方法是在小括號,中括號,大括號中使用Python隱式換行。長行能夠在表達式外面使用小括號來變成多行。連續行使用反斜槓更好。

反斜槓有時可能仍然是合適的。例如,長的多行的with語句不能用隱式續行,能夠用反斜槓:

article4.png

(爲進一步思考With語句的多行縮進,見前面多行if語句的討論。)


另外一個這樣的例子是assert語句。

確保適當的連續行縮進。

 

換行應該在二元操做符的前面仍是後面?

 

過去二十年咱們都是推薦放在二元操做符的後面。可是這種作法會以兩種方式傷害可讀性:多個二元操做符在屏幕上不在一列,另外若是你想知道對一個被操做的對象作了什麼操做,須要向上找一行。這致使你的眼睛不得不上下往返不少次才能搞清楚哪一個數字是被加的,哪一個數字是被減的:

article4.png

爲了解決可讀性問題,數學家和印刷業者一般是在二元操做符以前換行的。Donald Knuth在他的《計算機與排版》系列文章中解釋了這個傳統規則:「雖然寫在一段話中的公式常常在二元操做符的後面換行,可是單獨展現的公式一般是在二元操做符的前面換行。」

出於遵循數學傳統,因此咱們這樣寫這段代碼將更加可讀:

article4.png

 

空行

 

頂級函數和類的定義之間有兩行空行。

類內部的函數定義之間有一行空行。

額外的空行用來(謹慎地)分離相關的功能組。相關的行(例如:一組虛擬實現)之間不使用空行。

在函數中謹慎地使用空行來表示邏輯部分。

Python接受control-L(即^L)換頁符做爲空白符;許多工具把這些字符做爲分頁符,因此你可使用它們爲文件中的相關部分分頁。注意,一些編輯器和基於Web的代碼查看器可能不能識別control-L是換頁,將顯示另外的字形。

 

源文件編碼

 

Python核心發佈中的代碼應該始終使用UTF-8(或Python2中用ASCII)。
文件使用ASCII(Python2中)或UTF-8(Python3中)不該有編碼聲明。

在標準庫中,非默認編碼僅用於測試目的或註釋或文檔字符串須要說起包含非ASCII字符的做者名;不然,使用\x,\u,\U,或\N是字符串中包含非ASCII數據的首先方式。

Python3.0及以上版本,爲標準庫(參見PEP 3131)規定如下策略:Python標準庫中的全部標識符必須使用ASCII標識符,在可行的地方使用英文單詞(在不少例子中,使用非英文的縮寫和專業術語)。另外,字符串和註釋必須用ASCII。僅有的例外是(a)測試非ASCII的特色,(b)測試做者名。不是基於拉丁字母表的做者名必須提供一個他們名字的拉丁字母表的音譯。

開源項目面向全球,鼓勵採用統一策略。

 

導入

 

導入一般是單獨一行,例如:
風格良好:

article4.png


風格不良:

article4.png

 

這樣也是能夠的:

article4.png


導入經常位於文件頂部,在模塊註釋和字符串文檔以後,在模塊的全局變量和常量以前。

導入應該按照如下順序分組:
1. 標準庫導入
2. 相關的第三方導入
3. 特定的本地應用/庫導入
在每一個導入組之間放一行空行。

把任何相關__all__規範放在導入以後。
推薦絕對導入,由於它們更易讀,而且若是導入系統配置的不正確(例如當包中的一個目錄結束於sys.path)它們有更好的表現(至少給出更好的錯誤信息):
article4.png
明確的相對導入能夠用來接受替代絕對導入,特別是處理複雜包佈局時,絕對導入過於冗長。
article4.png
標準庫代碼應該避免複雜包佈局並使用絕對導入。
隱式的相對導入應該永遠不被使用,而且在Python3中已經移除。
從一個包含類的模塊中導入類時,一般下面這樣是好的寫法:
article4.png

若是這種寫法致使本地名字衝突,那麼就這樣寫:
article4.png

並使用「myclass.MyClass」和「foo.bar.yourclass.YourClass」來訪問。
避免使用通配符導入(from <模塊名> import *),由於它們使哪些名字出如今命名空間變得不清楚,這混淆了讀者和許多自動化工具。通配符導入有一種合理的使用狀況,從新發佈一個內部接口做爲一個公共API的一部分(例如,重寫一個純Python實現的接口,該接口定義從一個可選的加速器模塊而且哪些定義將被重寫提早並不知道)。

用這種方式從新命名,下面的有關公共和內部接口的指南仍適用。

 

模塊級別的內置屬性

 

模塊級別的內置屬性(名字有先後雙下劃線的),例如__all__, __author__, __version__,應該放置在模塊的文檔字符串後,任意import語句以前,from __future__導入除外。Python強制要求from __future__導入必須在任何代碼以前,只能在模塊級文檔字符串以後。

article4.png

 

字符串引號

 

Python中,單引號字符串和雙引號字符串是同樣的。本PEP不建議如此。建議選擇一條規則並堅持下去。當一個字符串包含單引號字符或雙引號字符時,使用另外一種字符串引號來避免字符串中使用反斜槓。這提升可讀性。

三引號字符串,與PEP 257 文檔字符串規範一致老是使用雙引號字符。

 

表達式和語句中的空格

 

沒法忍受的

 

如下狀況避免使用多餘的空格:

 

緊挨着小括號,中括號或大括號。

article4.png

緊挨在逗號,分號或冒號前:

article4.png

在切片中冒號像一個二元操做符,冒號兩側的有相等數量空格(把它看做最低優先級的操做符)。在一個擴展切片中,兩個冒號必須有相等數量的空格。例外:當一個切片參數被省略時,該空格被省略。

article4.png

緊挨着左括號以前,函數調用的參數列表的開始處:

article4.png

緊挨着索引或切片開始的左括號以前:

article4.png

爲了與另外的賦值(或其它)操做符對齊,不止一個空格。

article4.png

 

其它建議

 

始終避免行尾空白。由於它們一般不可見,容易致使困惑:若是\後面跟了一個空格,它就不是一個有效的續行符了。不少編輯器不保存行尾空白,CPython項目中也設置了commit前檢查以拒絕行尾空白的存在。

始終在這些二元操做符的兩邊放置一個空格:賦值(= ),加強賦值(+= ,-= 等),比較(== , < , > , != , <> , <= , >= ,in , not in ,is ,is not ),布爾(and ,or ,not )。
若是使用了不一樣優先級的操做符,在低優先級操做符周圍增長空格(一個或多個)。不要使用多於一個空格,二元運算符兩側空格數量相等。

article4.png

當=符號用於指示關鍵字參數或默認參數值時,它周圍不要使用空格。

article4.png

帶註解的函數使用正常的冒號規則,而且在->兩側增長一個空格:

article4.png

若是參數既有註釋又有默認值,在等號兩邊增長一個空格(僅在既有註釋又有默認值時才加這個空格)。

article4.png

不鼓勵使用複合語句(同一行有多條語句)。

article4.png

儘管有時if/for/while的同一行跟一小段代碼,在一個多條子句的語句中不要如此。避免摺疊長行!

article4.png

 

何時使用尾部逗號?

 

尾部逗號一般都是可選的,除了一些強制的場景,好比元組在只有一個元素的時候須要一個尾部逗號。爲了代碼更加清晰,元組只有一個元素時請務必用括號括起來(語法上沒有強制要求):

article4.png

當尾部逗號不是必須時,若是你用了版本控制系統那麼它將頗有用。當列表元素、參數、導入項將來可能不斷增長時,留一個尾部逗號是一個很好的選擇。一般的用法是(好比列表)每一個元素獨佔一行,而後尾部都有逗號,在最後一個元素的下一行寫閉標籤。若是你的數據結構都是寫在同一行的,就沒有必要保留尾部逗號了。

article4.png

 

註釋

 

同代碼相矛盾的註釋比沒有註釋更差。當代碼修改時,始終優先更新註釋!

註釋應該是完整的句子。若是註釋是一個短語或句子,它的第一個單詞的首字母應該大寫,除非它是一個以小寫字母開頭的標識符(不更改標識符的狀況下!)。

若是註釋很短,末尾能夠不加句號。註釋塊一般由一個或多個段落組成,這些段落由完整的句子組成,而且每一個句子都應該以句號結尾。

在句尾的句號後邊使用兩個空格。

寫英語註釋時,遵循斷詞和空格。

非英語國家的Python程序員:請用英語書寫註釋,除非你120%的肯定,全部看你代碼的人都和你說同樣的語言。

非英語國家的Python程序員:請寫下你的意見,在英語中,除非你是120%確定,代碼將不會被不講你的語言的人閱讀。

 

註釋塊

 

註釋塊一般適用於一些(或所有)緊跟其後的代碼,而且那些代碼應使用相同級別的縮進。註釋塊的每行以一個#和一個空格開始(除非註釋裏面的文本有縮進)。

註釋塊內的段落之間由僅包含#的行隔開。

 

行內註釋

 

謹慎地使用行內註釋。

行內註釋就是註釋和代碼在同一行,它與代碼之間至少用兩個空格隔開。而且它以#和一個空格開始。

若是行內註釋指出的是顯而易見,那麼它就是沒必要要的。  不要這樣作:
article4.png

但有時,這樣是有用的:
article4.png

 

文檔字符串

 

編寫好的文檔字符串(即「代碼」)約定在PEP 257中是永存的。

爲全部公共模塊,函數,類和方法書寫文檔字符串。對非公開的方法書寫文檔字符串是沒有必要的,但應該寫註釋描述這個方法是作什麼的。這些註釋應該寫在def行後面。
PEP 257描述了好的文檔字符串約定。最重要的是,多行文檔字符串以一行"""結束,例如:
article4.png

對於只有一行的文檔字符串,"""同一行上。

 

命名規範

 

Python庫的命名規範有點兒混亂,因此咱們不會將他們變得徹底一致——不過,這是目前推薦的命名標準。新模塊和包(包括第三方框架)應該按這些標準書寫,但對有不一樣的風格的已有庫,保持內部一致性是首選。

 

根本原則

 

用戶可見的API的公開部分的名稱,應該遵循反映用法而不是實現的約定。

 

描述:命名風格

 

有不少不一樣的命名風格。它有助於識別使用了什麼樣的命名風格,這獨立於他們的做用。

下面的命名風格是最多見的:

  • b(單個小寫字母)

  • B(單個大寫字母)

  • 小寫字符串

  • 帶下劃線的小寫字符串

  • 大寫字符串

  • 帶下劃線的大寫字符串

  • 首字母大寫的字符串(或CapWords,或駝峯命名法——因其字母看起來高低不平而得名[3])。這有時也被稱爲StudlyCaps。

   注意:當CapWords中使用縮寫,大寫全部的縮寫字母。所以HTTPServerError優於HttpServerError。

  • 混用大小寫的字符串(與首字母大寫字符串不一樣的是它以小寫字母開頭)

  • 帶下劃線的首字母大寫字符串(使人厭惡的!)


還有一種風格,使用簡短獨特的前綴組織相關的名字在一塊兒。Python中不多這樣用,提一下是爲了文檔的完整性。例如,os.stat()函數返回一個元祖,它的元素名字一般相似st_mode,st_size,st_mtime等等這樣。(這樣作是爲了強調與POSIX系統調用結構體一致,這有助於程序員熟悉這些。)

X11庫的全部的公開函數以X開頭。Python中,這種風格一般認爲是沒必要要的,由於屬性名和函數名以對象名做前綴,而函數名以模塊名做前綴。

 

另外,如下特殊形式,前導或後置下劃線是公認的(通常能夠與任何約定相結合):

  • 單前導下劃線:弱「內部使用」標誌。例如 from M import *不會導入如下劃線開頭的對象。

  • 單後置下劃線:按慣例使用避免與Python關鍵字衝突,例如。

     Tkinter.Toplevel(master, class_='ClassName')

  • 雙前導下劃線:當命名類屬性,調用時名稱改編(類FooBar中,__boo變成 _FooBar__boo;見下文)。

  • 前導和後置都是雙下劃線:存在於用戶控制的命名空間的「神奇」的對象或屬性。

    例如:__init__,__import__或__file__。不要創造這樣的名字;僅像文檔中那樣使用他們。

 

規定:命名約定

 

避免採用的名字

 

不要使用字符‘l’(小寫字母el),‘O’(大寫字母oh)或‘I’(大寫字母eye)做爲單字符變量名。

在某些字體中,這些字符與數字1和0是沒有區別的。當想使用‘l’時,用‘L’代替。

 

包名和模塊名

 

模塊名應該短,全部的字母小寫。能夠在模塊名中使用下劃線來提升可讀性。Python包名也應該短,全部的字母小寫,不鼓勵使用下劃線。

當一個C或C++書寫的擴展模塊,伴隨Python模塊來提供了一個更高層次(例如更面向對象)的接口時,C/C++模塊名有一個前導下劃線(如_socket)。

 

類名

 

類名一般使用首字母大寫字符串的規則。

函數的命名規則  主要用來可調用的。

在接口被記錄而且主要用做調用的狀況下,用函數的命名規則來代替類名的命名規則。

注意內置名有一個單獨的規則:大多數的內置名是一個單詞(或兩個單詞一塊兒),首字母大寫字符串的規則僅用於異常名和內置常量。

 

類型變量名稱

 

類型變量名稱應該首字母大寫,而且儘可能短,好比:T, AnyStr, Num。對於協變量和有協變行爲的變量,建議添加後綴__co或者__contra。

article4.png

 

異常名

 

由於異常應該是類,因此類的命名規則在這裏也一樣適用。然而,異常名(若是這個異常確實是一個錯誤)應該使用後綴「Error」。

 

全局變量名

 

(但願這些變量是在一個模塊內使用。)這些規則和那些有關函數的規則是相同的。

模塊設計爲經過from M import *來使用,應使用__all__機制防止導出全局變量,或使用加前綴的舊規則,爲全局變量加下劃線(可能你像代表這些全局變量是「非公開模塊」)。

 

 

函數名

 

函數名應該是小寫字母,必要時單詞用下劃線分開以提升可讀性。

混合大小寫僅用於這種風格已經占主導地位的上下文(例如threading.py),以保持向後兼容性。

 

函數和方法參數

 

使用self作實例化方法的第一個參數。

使用cls作類方法的第一個參數。

若是函數的參數名與保留關鍵字衝突,最好是爲參數名添加一個後置下劃線而不是使用縮寫或拼寫錯誤。

所以class_ 比clss好。(也許使用同義詞來避免更好。)。

 

方法名和實例變量

 

採用函數命名規則:小寫字母,必要時單詞用下劃線分開以提升可讀性。

僅爲非公開的方法和實例變量使用一個前導下劃線。

爲了不和子類命名衝突,使用兩個前導下劃線調用Python的名稱改編規則。

Python用類名改編這些名字:若是類Foo有一個屬性名爲__a,經過Foo.__a不能訪問。(能夠經過調用Foo._Foo__a來訪問。)通

常,兩個前導下劃線僅用來避免與子類的屬性名衝突。

注意:關於__names的使用存在一些爭論(見下文)。

 

常量

 

常量一般定義於模塊級別而且全部的字母都是大寫,單詞用下劃線分開。例如MAX_OVERFLOW和TOTAL。

 

繼承的設計


肯定類的方法和實例變量(統稱爲:「屬性」)是否公開。若是有疑問,選擇非公開;以後把其變成公開比把一個公開屬性改爲非公開要容易。

公開屬性是那些你指望與你的類不相關的客戶使用的,根據你的承諾來避免向後不兼容的變動。非公開屬性是那些不打算被第三方使用的;你不保證非公開屬性不會改變甚至被刪除。

非公共屬性是那些不打算被第三方使用的,你不能保證非公開的屬性不會改變甚至被刪除。

此處沒有使用術語「private」,由於Python中沒有真正私有的屬性(沒有一般的沒必要要的工做)。

屬性的另外一個類別是「API子集」的一部分(在其它語言常被稱爲「protected」)。某些類被設計爲基類,要麼擴展,要麼修改某些方面的類的行爲。在設計這樣的類的時候,要注意明確哪些屬性是公開的,哪些是API子類的一部分,哪些是真正只在你的基類中使用。


清楚這些以後,這是Python特點的指南:

  • 公開屬性沒有前導下劃線。

  • 若是公開屬性名和保留關鍵字衝突,給屬性名添加一個後置下劃線。這比縮寫或錯誤拼寫更可取。(然而,儘管有這樣的規定,對於任何類的變量或參數,特別是類方法的第一個參數,‘cls’是首選的拼寫方式)

           注1:參見上面對類方法的參數名的建議。

  • 對於簡單的公開數據屬性,最好只暴露屬性名,沒有複雜的訪問器/修改器方法。記住,Python爲將來加強提供了一條簡單的途徑,你應該發現簡單的數據屬性須要增長功能行爲。在這種狀況下,使用屬性來隱藏簡單數據屬性訪問語法後面的功能實現。

           注1:特性僅工做於新風格的類。
           注2:儘可能保持功能行爲無反作用,儘管反作用如緩存一般是好的。
           注3:計算開銷較大的操做避免使用特性,屬性註解使調用者相信訪問(相對)是廉價的。

  • 若是肯定你的類會被子類化,並有不想子類使用的屬性,考慮用兩個前導下劃線無後置下劃線來命名它們。這將調用Python的名稱改編算法,類名將被改編爲屬性名。當子類不無心間包括相同的屬性名時,這有助於幫助避免屬性名衝突。

          注1:注意改編名稱僅用於簡單類名,若是一個子類使用相同的類名和屬性名,仍然會有名字衝突。
          注2:名稱改編會帶來必定的不便,如調試和__getattr__()。然而,名稱改編算法有良好的文檔,也容易手工執行。
          注3:不是每一個人都喜歡名稱改編。嘗試平衡避免意外的名稱衝突和高級調用者的可能。

 

公共和內部接口

 

任何向後兼容性保證只適用於公共接口。所以,重要的是用戶可以清楚地區分公開和內部接口。

 

文檔接口被認爲是公開的,除非文檔明確聲明他們是臨時或內部接口,免除一般的向後兼容保證。全部非文檔化的接口應假定爲內部接口。

 

爲了更好的支持自省,模塊應該使用__all__屬性顯示聲明他們公開API的名字, __all__設置爲一個空列表表示該模塊沒有公開API。
即便__all__設置的適當,內部接口(包,模塊,類,函數,屬性或者其它名字)仍應以一個前導下劃線做前綴。

 

一個接口被認爲是內部接口,若是它包含任何命名空間(包,模塊,或類)被認爲是內部的。

 

導入名被認爲是實現細節。其它模塊必須不依賴間接訪問這個導入名,除非他們是一個明確的記錄包含模塊的API的一部分,例如os.path或包的__init__模塊,從子模塊暴露功能。


程序設計建議


編寫的代碼應該不損害其餘方式的Python實現(PyPy,Jython,IronPython,Cython,Psyco等等)。

 

例如,不要依賴CPython的高效實現字符串鏈接的語句形式 += b或a = a + b。這種優化即便在CPython裏也是脆弱的(它只適用於某些類型),而且在不使用引用計數的實現中它徹底不存在。在庫的性能易受影響的部分,應使用''.join()形式。這將確保跨越不一樣實現的鏈接發生在線性時間。

 

與單值好比None比較使用is 或is not ,不要用等號操做符。

 

一樣,若是你真正的意思是if x is not None,謹防編寫if x。例如,當測試一個默認是None的變量或參數是否被置成其它的值時。這個其它值多是在布爾上下文爲假的類型(例如容器)。

 

使用is not 操做符而不是not...is。雖然這兩個表達式的功能相同,前者更具備可讀性而且更優。

article4.png

當實現有豐富的比較的排序操做時,最好實現全部六個操做符(__eq__,__ne__,__lt__,__le__,__gt__,__ge__)而不是依靠其它代碼只能進行一個特定的比較。

 

爲了減小所涉及的工做量,functools.total_ordering()裝飾器提供了一個工具來生成缺失的比較函數。

 

PEP 207代表,Python假定自反性規則。所以,編譯器能夠交換y > x和x < y,y >= x和x <= y,也能夠交換參數x == y和x != y。sort()和min()操做保證使用< 操做符而且max()功能使用> 操做符。無論怎樣,最好實現全部六個操做,這樣在其它上下文就不會產生混淆了。

 

使用def語句而不是使用賦值語句將lambda表達式綁定到標識符上。

article4.png

第一種形式意味着所得的函數對象的名稱是‘f’而不是通常的‘<lambda>’。這在回溯和字符串表示中更有用。賦值語句的使用消除了lambda表達式能夠提供顯示def聲明的惟一好處(例如它能夠嵌在更大的表達式裏面)。

 

從Exception而不是BaseException中派生出異常。直接繼承BaseException是保留那些捕捉幾乎老是錯的異常的。

 

設計異常層次結構基於區別,代碼可能須要捕獲異常,而不是捕獲產生異常的位置。旨在以編程方式回答問題「出了什麼問題?」,而不是隻說「問題產生了」(參見PEP 3151對這節課學習內置異常層次結構的一個例子)

 

類的命名規則適用於此,只是當異常確實是錯誤的時候,須要在異常類名添加「Error」後綴。用於非本地的流控制或其餘形式的信號的非錯誤的異常,不須要特殊的後綴。

 

適當使用異常鏈。Python3中,「raise X from Y」用來代表明確的更換而不失去原來追蹤到的信息。

 

當故意替換一個內部異常(Python 2中使用「raise X」而Python 3.3+中使用「raise X from None」),確保相關的細節被轉移到新的異常中(好比當轉換KeyError爲AttributeError時保留屬性名,或在新的異常消息中嵌入原始異常的文本)。

 

Python 3中產生異常,使用raise ValueError('message')替換老的形式raise ValueError,'message'。

後一種形式是不合法的Python 3語法。

 

目前使用的形式意味着當異常的參數很長或包含格式化字符傳時,多虧了小括號沒必要再使用續行符。
捕獲異常時,儘量說起特定的異常,而不是使用空的except:子句。
例如,使用:

article4.png

空的except:子句將捕獲SystemExit和KeyboardInterrupt異常,這使得很難用Control-C來中斷程序,也會掩飾其它的問題。若是想捕獲會致使程序錯誤的全部異常,使用except Exception:(空異常至關於except BaseException:)
一條好的經驗法則是限制使用空‘except’子句的兩種狀況:

       1.若是異常處理程序將打印或記錄跟蹤;至少用戶將會意識到有錯誤發生。
       2.若是代碼須要作一些清理工做,可是隨後讓異經常使用raise拋出。處理這種狀況用try...finally更好。

當用一個名字綁定捕獲異常時,更喜歡Python2.6中添加的明確的名稱綁定語法。

article4.png

這是Python3中惟一支持的語法,並避免與舊的基於逗號的語法有關的歧義問題。

捕獲操做系統異常時,更喜歡Python 3.3引進的明確的異常層次,經過errno值自省。

另外,對於全部的try/except子句,限制try子句到必須的絕對最少代碼量。這避免掩蓋錯誤。

article4.png

當一個資源是一個局部特定的代碼段,它使用後用with語句確保迅速可靠的將它清理掉。也可使用try/finally語句。
不管什麼時候作了除了獲取或釋放資源的一些操做,應該經過單獨的函數或方法調用上下文管理器。例如:

article4.png

後者的例子沒有提供任何信息代表__enter__和__exit__方法作了什麼除了事務結束後關閉鏈接。 在這種狀況下,明確是很重要的。
返回語句保持一致。函數中的全部返回語句都有返回值,或都沒有返回值。若是任意一個返回語句有返回值,那麼任意沒有返回值的返回語句應該明確指出return None,而且明確返回語句應該放在函數結尾(若是能夠)。

article4.png

使用字符串方法代替string模塊。

字符串方法老是更快而且與unicode字符串使用相同的API。若是必須向後兼容Python2.0之前的版本,無視這個原則。
使用「.startswith() 」和「.endswith()」代替字符串切片來檢查前綴和後綴。

startswith()和endswith()更清晰,而且減小錯誤率。例如:

article4.png

對象類型的比較使用isinstance()代替直接比較類型。

article4.png

當檢查一個對象是不是字符串時,牢記它也多是一個unicode字符串!Python 2中,str和unicode有共同的基類basestring,因此你能夠這麼作:

article4.png

注意,Python3中, unicode和basestring再也不存在(只有str),而且字節對象再也不是string(而是一個integers序列)
對於序列(字符串,列表,元組),利用空序列是false的事實。

article4.png

不要書寫依賴後置空格的字符串。這些後置空格在視覺上沒法區分,而且有些編輯器(或最近,reindent.py)將去掉他們。
不要用==來將布爾值與True或False進行比較。

article4.png

Python標準庫不使用函數註解,因爲它將給一個特定的註釋風格形成過早的承諾。相反,註釋是留給用戶去發現和試驗的有用的註釋樣式。

 

建議第三方實驗註釋使用一個相關的修飾符代表解釋器若是解釋註解來試驗註解。

 

早期的核心開發人員嘗試使用顯示不一致的函數註解,特別的註釋風格。例如:

[str]是模糊的,它是表明一個字符串列表仍是一個能夠是str或None的值。

 

符號open(file:(str,bytes))被用於值是 bytes或str替代包含一個str緊跟一個bytes值的二元元組。

 

seek(whence:int)註解展現出了一個規定外和規範內的混合:int限制太多(任何與__index__將被容許),它還不夠嚴格(只有值0,1,和2是容許的)。一樣的,write(b:bytes)註解也有太多限制(任何支持緩衝協議的將被容許)。

 

有些註解如read1(n:int=None)是自相矛盾的由於None不是一個int值。有些註解如assource_path(self,fullname:str) -> object,使人困惑它的返回類型是什麼。

 

除了以上的,註解在具體類型和抽象類型的使用上是不一致的:int與Integral相對,set/frozenset與MutableSet/Set相對。
抽象基類的一些註解是不正確的規範。例如,set-to-set操做須要Other是另外一個Set的實例而不是一個Iterable。

另外一個問題是註解成爲規範的一部分,但它沒有被測試。

 

在大多數狀況下,文檔字符串已經包含了類型規範,而且比函數註解更清晰。在其他的狀況下,一旦註解被移除文檔字符串將改進。
所見到的函數註解太特別並且與一個自動類型檢查或參數驗證的連貫系統不一致。在代碼中留下這些註解將使它之後更難作出改變以便自動化工具支持。

腳註

 

[5]懸掛縮進是段落中除第一行以外其它全部行都縮進的格式。在Python中,這個術語用來描述左括號括起來的語句,這行的最後非空白的字符,隨後行縮進,直到右括號。

 

參考

 

[1]PEP 7,van Rossum寫的C編碼風格指南
[2]Barry的GNU Mailman風格指南
 http://barry.warsaw.us/software/STYLEGUIDE.txt
[3]http://www.wikipedia.com/wiki/CamelCase
[4]PEP 8現代化,2013年7月http://bugs.python.org/issue18472
版權
這個文檔已經放置在公共領域。
來源:https://hg.python.org/peps/file/tip/pep-0008.txt

 

 

英文原文: https://www.python.org/dev/peps/pep-0008/

譯者: wangyc

相關文章
相關標籤/搜索