天天看點

Python 基礎編碼風格

一、 基礎風格:遵循PEP

  1. 語句編排:
    • 每個語句獨占一行,勿在行尾加分号, 也不要用分号将多條語句放在同一行。
    • 另起一行,即使定義,語句較為簡單:
      • if/for/while 語句中
      • 類定義:

        class UnfoundError(Exception): pass

    • 建議多行: 
      • 函數和方法的括号中參數或者元素過多時,建議換行多層縮進書寫解決
  2. 空格使用:
    • 不加空格:
      • 各類括号内接語句前後不加空格 
      • 參數中預設值 
    • 加空格: 基本符号後(口号,冒号)前不加空格,後加  使用等号的場景(除參數預設值)  
  3. 命名規範:
    • 小寫配合下劃線場景:
      • 檔案名 
      • 類方法和屬性 
    • 駝峰場景:
      • 類名 
    • 大寫與下劃線配合場景:
      • 全局變量名 
    • 下劃線使用開頭(同樣應用于子產品,檔案):
      • 為其執行個體的私有方法(預設:不建議執行個體外部調用,但不影響擷取其值)
    •  雙下劃線開頭(同樣應用于子產品,檔案):
      • 為其私有方法,不允許外部調用,僅可在内部方法之間使用(原因:是防止調用,内部進行了對進行了重載) 
      • 在不重載類屬性時,不建議定義以雙下劃線開頭和結尾的方法 
  4. 判斷比較:
    • 可能的話使用 is/is not 代替 ==(并不是所有的都可以,== 與 is 不等價) 
    • 使用 isinstance() 比較對象的類型,而不是 type() 
    • 使用 startswith() 和 endswith() 代替切片進行序列字首或字尾的檢查。 
    • if、while、for 時無需專門使用語句判斷對象真值 
  5. 拼接:
    • 字元串,list,tuple等,建議使用join 替代 + ;
    • 路徑拼接,如果跨平台,建議使用os.path.join or pathlib 
  6. 效率: 使用疊代器和生成器代替清單等資料結構效率更高,使用清單(字典)解析式和生成器表達式比用循環效率更高。
  7. 好的習慣:
    • try: ... except ...., except 後面異常類型确認的話,明确寫上各類型 
    • 檔案子產品:功能結構衆多,期望有if __name__ == "__main__" 代碼塊,标準函數執行邏輯過程: 
      if__name__ =="__main__":
          do1()
          do2()           
    • 使用推導式,map,filter,reduce等代替for,while循環處理
    • 包子產品擁有自己定義的異常類型
    • 類的方法第一個參數必須是self,而靜态方法第一個參數必須是cls。盡可能的使用 classmethod, staticmethod

二、特别:

    1. 子產品導入格式

  • 位于最頂層,或者頂層注釋與代碼塊中間
  • 導入應該按照從最通用到最不通用的順序分組: 
    • 标準庫導入
    • 第三方庫導入
    • 應用程式指定導入
  • 不建議使用 from flask import * 形式導入,污染全局變量
  • 針對子產品檔案中存在大量函數情況下,建議使用__all__ 标注可供外部直接使用的函數

    2.  涉及到IO操作的,注意對象IO對象的關閉,可能的話建議了解是否可用 with

with open("hello.txt") as fr:
    for line in fr:
        pass           

       網絡請求包:requests,urllib等sockets連接配接相關,因記憶體管理存在,析構函數可能被無線延長,在大并發高頻次網絡請求時,會産生嚴重的記憶體洩漏

    3. 建議使用 TODO 為項目代碼添加臨時注釋

三、 工程:

    1. 函數:Python是一門動态語言,很多時候我們可能不清楚函數參數類型或者傳回值類型,可以通過 typing (Python3.5 之後内置方法,目前可能僅有Pycharm支援typing檢查)标注入參,傳回值類型,提高可讀性

  • 注釋:
  • 入參(:param):
  • 傳回值(:return)

 如下:使用基本類型與 typing類型标注配合,提高項目可讀性,IDE中擁有類型提示,不影響代碼的使用:https://docs.python.org/zh-cn/3.6/library/typing.html

from typing import List, Mapping, Optional
 
# 基礎函數定義标注
def func_merge(a: List[int], b: List[int or str], c: List) -> List[int or str]:
    """
    實作清單合并,産生新的清單
    :param a: 清單a
    :param b: 清單b
    :param c: 清單c
    :return: 生成新的清單
    """
    return a + b + c
 
 
func_merge(1, 2, 0)  # Pycharm 上會變黃有提示: Expected type 'list', got 'int' instead
func_merge([1], [2], [0])
 
 
# 回調函數定義标注
def do(a: int):
    return str(a)
 
 
def run_callback(num: int, cb: Callable[[int], str]) -> str:
    return cb(num)
 
 
print(run_callback(123456, do))
print(run_callback("a", do))  # 變黃
 
# 可變參數定義标注
def foo(arg: Optional[int] = 0) -> None:
    print("arg:", arg)
 
 
# foo(arg="a")  # 以不正确形式
# foo(arg=1)
foo()
 
# 變量定義标注
conf: Mapping[str, str]
conf = {"REDIS": 12323}           
  • 接口功能單一
  • 視圖函數,建議以類形式進行處理,django/flask的views,或者restful 的Resource:
    • 方法功能明确:get/post/put/delete 
    • 方法,功能可聚合
    • 結構繼承
  • 請求:資源階層化,利于閱讀與網關權限控制
{
    "code": 0,         # 0, 接口預期響應,非0:異常響應
    "data": {},        # 傳回具體結果詳情
    "message": "",     # 響應描述
    "desc": "",        # desc 接口功能描述
    "time": ""         # 傳回響應時間
}