PEP8規範總結
PEP8 是什麼呢,簡單說就是一種編碼規範,是爲了讓代碼「更好看」,更容易被閱讀。 具體有這些規範,參考 PEP 8 --Style Guide for Python Code.固然也可使用Pycharm檢查或使用pylint.下面是規範總結python
縮進
- 不要使用 tab 縮進
- 使用任何編輯器寫 Python,請把一個 tab 展開爲 4 個空格
- 絕對不要混用 tab 和空格,不然容易出現 IndentationError
空格
- 在 list, dict, tuple, set, 參數列表的 , 後面加一個空格
- 在 dict 的 : 後面加一個空格
- 在註釋符號 # 後面加一個空格,可是 #!/usr/bin/python 的 # 後不能有空格
- 操做符兩端加一個空格,如 +, -, *, /, |, &, =
- 接上一條,在參數列表裏的 = 兩端不須要空格
- 括號((), {}, [])內的兩端不須要空格
空行
- function 和 class 頂上兩個空行
- class 的 method 之間一個空行
- 函數內邏輯無關的段落之間空一行,不要過分使用空行
- 不要把多個語句寫在一行,而後用 ; 隔開
- if/for/while 語句中,即便執行語句只有一句,也要另起一行
換行
- 每一行代碼控制在 80 字符之內
- 使用 \ 或 () 控制換行,舉例:
def foo(first, second, third, fourth, fifth,
sixth, and_some_other_very_long_param):
user = User.objects.filter_by(first=first, second=second, third=third) \
.skip(100).limit(100) \
.all()
text = ('Long strings can be made up '
'of several shorter strings.')
命名
- 使用有意義的,英文單詞或詞組,絕對不要使用漢語拼音
- package/module 名中不要出現 -
- 各類類型的命名規範:
Type |
public |
Inernal |
Modules |
lower_with_under |
_lower_with_under |
Packages |
lower_with_under |
|
Classes |
CapWords |
_CapWords |
Exceptions |
CapWords |
|
Functions |
lower_with_under() |
_lower_with_under() |
Global/Class Constans |
CAPS_WITH_UNDER |
CAPS_WITH_UNDER |
Global/Class Variables |
lower_with_under |
_lower_with_under |
Instance Variables |
lower_with_under |
_lower_with_under(protected)or __lower_with_under |
Method Names |
lower_with_under() |
_lower_with_under(protected)or __lower_with_under |
Function/Method Parameters |
lower_with_under |
|
Local Variables |
lower_with_under |
|
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 下的內容能夠寫一塊兒:算法
# bad
import sys, os, time
# good
import os
import sys
import time
# ok
from flask import Flask, render_template, jsonify
- 爲了不可能出現的命名衝突,可使用 as 或導入上一級命名空間
- 不要出現循環導入(cyclic import)
註釋
- 文檔字符串 docstring, 是 package, module, class, method, function 級別的註釋,能夠經過 doc 成員訪問到,註釋內容在一對 """ 符號之間
- function, method 的文檔字符串應當描述其功能、輸入參數、返回值,若是有複雜的算法和實現,也須要寫清楚
- 不要寫錯誤的註釋,不要無謂的註釋
# bad 無謂的註釋
x = x + 1 # increase x by 1
# bad 錯誤的註釋
x = x - 1 # increase x by 1
- 優先使用英文寫註釋,英文很差所有寫中文,不然更加看不懂
異常
- 不要輕易使用 try/except
- except 後面須要指定捕捉的異常,裸露的 except 會捕捉全部異常,意味着會隱藏潛在的問題
- 能夠有多個 except 語句,捕捉多種異常,分別作異常處理
- 使用 finally 子句來處理一些收尾操做
- try/except 裏的內容不要太多,只在可能拋出異常的地方使用,如:
# bad
try:
user = User()
user.name = "leon"
user.age = int(age) # 可能拋出異常
user.created_at = datetime.datetime.utcnow()
db.session.add(user)
db.session.commit() # 可能拋出異常
except:
db.session.rollback()
# better
try:
age = int(age)
except (TypeError, ValueError):
return # 或別的操做
user = User()
user.name = "leon"
user.age = age
user.created_at = datetime.datetime.utcnow()
db.session.add(user)
try:
db.session.commit()
except sqlalchemy.exc.SQLAlchemyError: # 或者更具體的異常
db.session.rollback()
finally:
db.session.close()
- 從 Exception 而不是 BaseException 繼承自定義的異常類
Class(類)
- 顯示的寫明父類,若是不是繼承自別的類,就繼承自 object 類
- 使用 super 調用父類的方法
- 支持多繼承,即同時有多個父類,建議使用 Mixin
字符串
- 使用字符串的 join 方法拼接字符串
- 使用字符串類型的方法,而不是 string 模塊的方法
- 使用 startswith 和 endswith 方法比較前綴和後綴
- 使用 format 方法格式化字符串
比較
- 空的 list, str, tuple, set, dict 和 0, 0.0, None 都是 False
- 使用 if somelist 而不是 if len(somelist) 判斷某個 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()
# bad
if d.has_key(k):
do_something()
# good
if k in d:
do_something()
- 用 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 等使用現有的優秀的解決方案