Python寫業務邏輯的幾個編碼原則

金色旭光發表於2021-12-20

作為一個寫業務邏輯的boy,我需要專注的就是把業務邏輯寫好。寫業務邏輯並不複雜,就是把程式設計最基礎的東西使用好,有變數迴圈流程控制函式資料庫等。
但是寫出的邏輯要通俗易懂、易於理解,避免炫技、晦澀。在目前團隊中待了一段時間了,根據 code review 和自己的理解整理出一些基本原則。

業務程式碼思想原則

第一:程式碼要足夠容易閱讀。

程式碼是給程式設計師閱讀的,首先要做到的就是邏輯清晰,易於閱讀。所以要避免毫無意義的變數名、巢狀過多的邏輯判斷、過於複雜的流程控制。在易讀性和效能兩者之間,首先要保證易讀性,當然兩者並不衝突。

第二:程式碼效能要有保證

python程式碼的執行速度比不上編譯性語言,所以要在程式碼層面上保證效能的可靠。通常解決一個主要降低效能的點,就能提升整體的效能。

業務程式碼編碼原則

變數

核心思想:清晰表示變數的功能
原則

  1. 變數命名統一,python推薦使用下劃線分隔命名法,即蛇形命名法,畢竟python就是蛇嘛。真實原因:Python 為什麼要推薦蛇形命名法
  2. 變數命名中可以帶資料型別,如 buy_user_listid_to_name_dict 。python的靈活性高,為了更加方便區分變數、函式、方法等,變數名加資料型別是個好方法
  3. 超過三個的常量都要用列舉值。善用列舉值,讓列舉值的名字解釋常量,這是遵守第一條原則,容易閱讀
  4. 多使用區域性變數少使用全域性變數,名稱空間中區域性變數優先搜尋

流程控制

核心思想:減少if else巢狀,邏輯越清晰越好
原則
減少if else

  1. 可以使用字典的key value特性,直接用key命中條件,避免if判斷。
  2. 使用裝飾器裝飾函式,裝飾器實現裡用字典特性做if else判斷。可參考:如何簡化大量的 if…elif…else 程式碼?
  3. 用in操作替換if else判斷。
  4. 使用any 或 all 將多個判斷一起處理,減少if else的分支

無法減少if else時要讓邏輯清晰

  1. 存在複雜的判斷條件時,可以先將判斷條件處理一遍。如一個判斷(a and b) or (c and d)操作時,先單獨判斷出 a and b 和 c and d,然後再判斷兩者結果
  2. 減少if else之間的處理流程。if或else中處理的流程過長時要儘量簡化流程處理,抽象出函式。讓if else對齊,處理的邏輯看起來清晰。
  3. if條件的短路特性。if a or b 這種判斷中,如果a是True就不會判斷b,所以將True條件寫在前面可以節省判斷時間

簡單小例子:使用 all 減少 if else


have_opencourse = True if plan_id in [1,2] else False

user_info = bayuser.get_user_info(user_id)
register_time = pendulum.parse(user_info.created_at)
register_at_today = True if register_time.date() == get_local_today() else False

checkin_days = uc.get_user_checkin_days(user_id)
checkin_zero_day = True if checkin_days == 0 else False

ab_test_id = 414
ab_test_name = words_utils.get_user_plan(user_id, ab_test_id).user_plan
no_provide = True if ab_test_name == "no_provide" else False

# 使用if else判斷
if register_time.date() == get_local_today() and checkin_days == 0 and ab_test_name == "no_provide" and plan_id in [1,2]:
    return encoder.json_response(code=200)
    
# 使用all判斷
if all([have_opencourse, register_at_today, checkin_zero_day, no_provide]):
    return encoder.json_response(code=200)

迴圈

核心思想:減少for迴圈
原則

  1. 用for迴圈代替while迴圈,for迴圈比while迴圈快
  2. 使用隱式for迴圈代替顯式for迴圈。如sum,map,filter,reduce等都是隱式for迴圈
  3. 儘量不要打斷迴圈。打斷迴圈的放在外面。有判斷條件的語句和與迴圈不相關的操作語句儘量放在for外面
  4. 應當將最長的迴圈放在最內層,最短的迴圈放在最外層,以減少CPU跨切迴圈層的次數
  5. for迴圈和集合都可以處理的選擇集合解決,集合的效率遠高於迴圈

簡單小例子:集合替代for迴圈

# for迴圈
for user in pay_user_cet4_set:
    if user not in all_presale_user_set:
        cet4_push.append(user)

# 集合操作
cet4_push = pay_user_cet4_set - all_presale_user_set

函式

核心思想:功能單一,短小精悍
原則

  1. 函式設計要儘量短小,巢狀層次不宜過深
  2. 一個函式只做一件事,儘量保證函式語句粒度的一致性。
  3. 函式申明應該做到合理,簡單,易於使用。函式名合理,引數不宜過多。
  4. 函式引數設計應該考慮向下相容。通過新增預設引數來實現。

小結

之前分享過一本如何優雅寫python的書,可以看之前寫的一篇文章:
改善python程式的91個建議

在每一個開發團隊都有會團隊的程式碼風格。優秀的程式碼風格讓團隊中龐大的程式碼井井有條,處處有規律可循,就像是一個人完成的。每一個人也要有自己的程式碼原則,缺少基本原則的指導會讓程式碼看起來不和諧,前後矛盾,這樣肯定是不利於個人成長的。

本文提到的原則並見得全部正確,只是我個人在實際工作中的真實總結,絕不是閉門造車,僅供參考,歡迎交流。後續總結的原則也會繼續更新到這裡。

相關文章