PEP 8 程式程式碼的編寫風格指南

Jason990420發表於2019-12-24

PEP 8 程式程式碼的編寫風格指南

參考

PEP 8 -- Style Guide for Python Code

介紹

PEP ( Python Enhancement Proposals ) - Python 語言精進建議書

本份檔案提供Python程式碼編寫的守則, 有關為Python 語言以C語編寫的部份請參考PEP 7.

如果某些專案具有特定的編寫風格, 以該專案為主.

這個愚笨的程式碼編寫一致性要求是來自於淘氣鬼的一點小心思.

編者意見:
這守則太過繁雜, 想遵守的人看了都會瘋了. 重點如果簡單, 很多人自然會遵循去作. 要不是受到Python相關人員的提示要求, 我肯定不會去管PEP 8的要求, 頂多就是三件事: 每行不超過80個字, 排版對齊, 加上一些說明.
本文非直接翻譯的結果, 如果有錯誤, 敬請提示.

程式碼被讀的機會比編寫的機會多, 這裡的守則, 目的在於改善程式碼的可讀性及各類不同應用的一致性.

不要只為了符合本守則, 而破壞了有關舊版的相容性.

可以忽視本守則的原因:

  1. 當應用本守則時, 會造成可讀性降低.
  2. 為了與周遭的程式碼一致, 可能是因為舊程式碼的存在.
  3. 在本守則建立以前的舊程式碼.
  4. 為了相容與不支援本守則的舊版Python.

程式碼的佈局

縮格

每一層級的縮格使用4個空格符, 不要使用Tab, 除非要相容原已使用Tab縮格的程式碼.

使用大中小括號來分行時應該要作到垂直對齊, 其中段落中除第一行外, 其他各行都應該要縮格. 左括號是第一行的最後一個非空白字元, 並且沒有任何的引數; 如果第一行的內容太短, 比如 if ( 就沒有必要這麼作. 右括號可以放在最後一行的第一個字.

如果分行的縮格無法與下一語句的縮格區分, 必須在分行前再加一級縮格.

每一行的最大長度

限制每一行的最大長度為79個字母. 檔案說明或批註最大長度為72個字母. 儘可能使用括號來分行, 而不要使用倒斜線, 除非前者無法使用.

二元運算子 (+, - ,* ,/ , ... )

運算子前分行會更有可讀性

空行的使用

  • 頂層函式及類的定義應該前後加兩個空行.
  • 類中的方法則前後加一個空行.
  • 相關功能的語句可以保守地使用空行與別的語句區隔.
  • 單行語句的空行可以省略.
  • 函式中邏輯的部份可以保守地使用空行.

原始碼的編碼方式

  • 永遠都使用 UTF-8 (在 Python 2 中使用的是 ASCII)
  • 使用 UTF-8 或 ASCII 不應該有編碼的宣稱.
  • 標準庫中, 非省缺的編碼只能用在測試時或檔案說明及批註中, 否則使用 \x, \u, \U 或 \N 脫離字元來包含非ASCII的資料.
  • 標準庫中, 所有的標示符必須使用ASCII, 也應該是英文字母. 字串及批註也必須是ASCII. 作者名是一個例外, 但必須轉譯為拉丁字母表 ( latin-1 )

Import

  • import 語句應該放在模組批註及檔案說明之後, 模組全域性變數及常數之前.
  • import 應該分為三群, 標準庫, 第三方庫, 自己的庫; 用空行來分隔
  • 建議使用絶對路徑 import; 標準庫應該使用絶對路徑 import. 不要使用隱式相對路徑的 import, Python 3 已經移除這種方式.
  • 不要使用 import *, 會造成命名的混淆或重複.
  • 不同模組不要寫在同一個 import 語句中, 同一個模組可以寫在一個import 語句中.

模組級的雙底線變數名

  • 除了 from __future__ import 以外, 所有雙線的變數名宣稱應該放在檔案說明之後, 其他 import 之前. Python 指定 from __future__ import 必須放在檔案說明之後, 以及其他程式碼之前.

字串引號

  • 字串的引號使用單引號或雙引號都是可以的.
  • 檔案說明則要使用三個雙引號.

表示式與語句中的空格

  • 避免額外多餘的空格
  • 括號前不要有空格.
  • 逗號前不要有空格.
  • 冒號前後空格數量要一樣.
  • 函式名, 類名及變數名後要緊接括號.
  • 不要為了對齊某個字而增加空格, 比如等號.

其他建議

  • 每一行的後面不要有空格.
  • 運算子前後都加上一個空格.
  • 不同運算順序的運算子, 可以考慮在運算順序較後的運算子前後各加一個空格.
  • 非 -> 的關鍵詞及預設值所使用的等號前後不要有空格. -> 時則要加空格.
  • -> 前後各加一個空格.
  • 不要使用超過一個的空格.
  • 不建議使用組合單行的語句

逗號在後

  • 只有一個元素的Tuple使用, 必須在括號內使用.

批註

  • 程式碼更新時, 也請更新批註.
  • 批註要是一個完整的句子; 第一個字除非是變數名, 否則應該要大寫; 每個句子結束要有句點; 兩個句子之間應該要有兩個空格.
  • 英文書寫請依循 "Strunk and White" ( 英文寫作指南 ).
  • 除非很確定程式碼不會被其他語言國家的人來讀, 否則請以英文來書寫.
  • 區塊批註中的段落使用一個 # 的空行來分隔.
  • 行批註少用, 使用時, 至少空兩個空格, # 後加一個空格, 語意明顯的就不用說明

檔案說明字串

  • 守則請看PEP 257.
  • 對所有的公開模組, 函式, 類以及方法, 要寫檔案說明字串.
  • 非公開的部份, 應該要有批註說明其用意, 批註放在 def 下一行.
  • """ 要單獨放在檔案說明字串的最後一行, 除非只有一行.

名字定義方式

  • 名字定義的方式所要反應的是用法, 而不建立.
  • 前置字在模組用來群組化是沒有意義的, 因為模組帶頭已經說明了一切.
  • 前有一底線的, 為弱內部使用, 在 import * 中, 不會被引入.
  • 後有一底線的, 用來避免與Python的闗鍵字混淆.
  • 前有雙底線的, 會造成與類名連線, 引起混淆.
  • 前後有雙底線的只在使用者所有的名空間內.

命名守則

  • 不要用小寫的 L, 大寫的 O, 大寫的 I, 來作為單字母的變數名.
  • 使用 ASCII 變數名.
  • 模組/庫 - 短的全小寫字母 (+中間底線, 不建議使用), C/C++模組前面要加一個底線.
  • 類 - 大寫字母開頭的字組
  • 內建 - 單一或兩個字的組合, 大寫字母開頭的字組只適用在exception名, 以及常數.
  • 變數名定義在 PEP 484, 為優先使用大寫字母開頭的字組, 後面加底線再加小寫的字, 以代表相應的變數.
  • 異常名字 - 同類的方式, 後面應加上底線及Error.
  • 全域性變數 - 在單一模組內使用, 如函式名一樣, 舊守則是在前面加上一個底線.
  • 函式及變數名 - 全小寫字母, 或可加上居中底線, 混合方式只限定已有的樣式, 以達到相容要求.
  • 函式與方法的引數 - 類的方法使用 cls 作為第一個引數, 例項方法使用 self 作為第一個引數. 如果函式的引數與關鍵詞衝突, 最好是加一個後底線, 或使用同意字, 而不是改名字.
  • 方法與例項 - 小寫字母, 或可加上居中底線, 如果是私有的方法或例項, 加一個前底線.
  • 避免與子類衝突, 加前雙底線, 將無法被外部直接取用, 但可間接取用(模組名._模組名+變數名)
  • 常數 - 全大寫+中底線
  • 公開的部份, 修改可能要考慮相容的問題; 公開的部份則不需要. 沒有檔案說明的介面都被視為非公開的.
  • 公開的屬性沒有前底線, 與關鍵詞衝突則加後底線.

程式設計建議

  • 程式碼的編寫不會破壞其他的程式碼. 比如字串的相加, 不要用 + 號, 最好是使用 ''.join()
  • 單態類的比較, 使用 is 或 is not, 而不要用 == 或 !=; 邏輯類的if result, 最好是 if result is not None. 使用 is not, 而不是 not is.
  • 順序的比較最好是使用 (__eq__, __ne__, __lt__, __le__, __gt__, __ge__), 可以用在不同的種類比較上. 可以參考 functools.total_ordering(), PEP 207.
  • 使用 def 好過使用 lambda
  • 從 Exception 找異常, 而不是從 BaseException 去找. PEP 3151
  • Exception 發生時, 應該把相關的細節都回傳到新的 Exception.
  • 指明發生的異常, 而不是隻有 except:.
  • try中的語句越少越好.
  • 當來源只適用某些語句時, 使用 with 方法/函式.
  • 所有的情況都應明白指出返回的結果.
  • 使用字串方法, 而不是使用字串模組.
  • 使用 ''.startswith() 與 ''.endswith() 代替檢查字串的前後文.
  • 使用 isinstance() 來檢查型別, 而不是type().
  • 空的string, list 與 tuple代表的是False.
  • 字串中後面的空格可能會被刪除.
  • 不要用 == 或 is 來比較 邏輯值.
  • 不要在 try ... finally 中使用 return/break/continue.
本作品採用《CC 協議》,轉載必須註明作者和本文連結
Jason Yang

相關文章