PEP8規則
阿新 • • 發佈:2021-01-03
PEP8 是什麼呢,簡單說就是一種編碼規範,是為了讓程式碼“更好看”,更容易被閱讀。
縮排
- 不要使用 tab 縮排
- 使用任何編輯器寫 Python,請把一個 tab 展開為 4 個空格
- 絕對不要混用 tab 和空格,否則容易出現
IndentationError
空格
- 在 list, dict, tuple, set, 引數列表的 , 後面加一個空格
- 在 dict 的 : 後面加一個空格
- 在註釋符號 # 後面加一個空格,但是
#!/usr/bin/python
的#
後不能有空格 - 操作符兩端加一個空格,如 +, -, *, /, |, &, =
- 接上一條,在引數列表裡的 = 兩端不需要空格
- 括號((), {}, [])內的兩端不需要空格
空行
- function 和 class 頂上兩個空行
- class 的 method 之間一個空行
- 函式內邏輯無關的段落之間空一行,不要過度使用空行
- 不要把多個語句寫在一行,然後用 ; 隔開
if/for/while
語句中,即使執行語句只有一句,也要另起一行
換行
- 每一行程式碼控制在 80 字元以內
- 使用 \ 或 () 控制換行。
命名
- 使用有意義的,英文單詞或片語,絕對不要使用漢語拼音
- package/module 名中不要出現 -
import
- 所有 import 儘量放在檔案開頭,在 docstring 下面,其他變數定義的上面
- 不要使用 from foo imort *
- import 需要分組,每組之間一個空行,每個分組內的順序儘量採用字典序,分組順序是:
- 標準庫
- 第三方庫
- 本專案的 package 和 module
- 不要使用隱式的相對匯入(implicit relative imports),可是使用顯示的相對匯入(explicit relative imports),如
from ..utils import parse
,最好使用全路徑匯入(absolute imports) - 對於不同的 package,一個 import 單獨一行,同一個 package/module 下的內容可以寫一起
- 為了避免可能出現的命名衝突,可以使用 as 或匯入上一級名稱空間
- 不要出現迴圈匯入(cyclic import)
註釋
- 文件字串 docstring, 是 package, module, class, method, function 級別的註釋,可以通過doc成員訪問到,註釋內容在一對 “”” 符號之間
- function, method 的文件字串應當描述其功能、輸入引數、返回值,如果有複雜的演算法和實現,也需要寫清楚
- 不要寫錯誤的註釋,不要無謂的註釋
- 優先使用英文寫註釋,英文不好全部寫中文,否則更加看不懂
異常
- 不要輕易使用 try/except
- except 後面需要指定捕捉的異常,裸露的 except 會捕捉所有異常,意味著會隱藏潛在的問題
- 可以有多個 except 語句,捕捉多種異常,分別做異常處理
- 使用 finally 子句來處理一些收尾操作
-
try/except 裡的內容不要太多,只在可能丟擲異常的地方使用
- 從
Exception
而不是BaseException
繼承自定義的異常類
Class(類)
- 顯示的寫明父類,如果不是繼承自別的類,就繼承自 object 類
- 使用 super 呼叫父類的方法
- 支援多繼承,即同時有多個父類,建議使用 Mixin
字串
- 使用字串的
join
方法拼接字串 - 使用字串型別的方法,而不是
string
模組的方法 - 使用
startswith
和endswith
方法比較字首和字尾 - 使用
format
方法格式化字串
比較
- 空的 list, str, tuple, set, dict 和 0, 0.0, None 都是 False
- 使用 if some_list 而不是 if len(some_list) 判斷某個 list 是否為空,其他型別同理
- 使用 is 和 is not 與單例(如 None)進行比較,而不是用 == 和 !=
- 使用 if a is not None 而不是 if not a is None
- 用 isinstance 而不是 type 判斷型別
- 不要用 == 和 != 與 True 和 False 比較(除非有特殊情況,如在 sqlalchemy 中可能用到)
-
使用 in 操作:
-
用 key in dict 而不是 dict.has_key()
- 用 set 加速 “存在性” 檢查,list 的查詢是線性的,複雜度 O(n),set 底層是 hash table, 複雜度 O(1),但用 set 需要比 list 更多記憶體空間
-
其他
- 使用列表表示式(list comprehension),字典表示式(dict comprehension, Python 2.7+) 和生成器(generator)
- dict 的 get 方法可以指定預設值,但有些時候應該用 [] 操作,使得可以丟擲 KeyError
- 使用 for item in list 迭代 list, for index, item in enumerate(list) 迭代 list 並獲取下標
- 使用內建函式 sorted 和 list.sort 進行排序
- 適量使用 map, reduce, filter 和 lambda,使用內建的 all, any 處理多個條件的判斷
- 使用 defaultdict (Python 2.5+), Counter(Python 2.7+) 等 “冷門” 但好用的標準庫演算法和資料結構
- 使用裝飾器(decorator)
- 使用 with 語句處理上下文
- 有些時候不要對型別做太過嚴格的限制,利用 Python 的鴨子型別(Duck Type)特性
- 使用 logging 記錄日誌,配置好格式和級別
- 瞭解 Python 的 Magic Method:A Guide to Python’s Magic Methods,Python 魔術方法指南
- 閱讀優秀的開原始碼,如Flask框架,Requests for Humans
- 不要重複造輪子,檢視標準庫、PyPi、Github、Google 等使用現有的優秀的解決方案