《Python 工匠》筆記(三)有關「變數」的程式設計建議
Python 工匠
這是《Python 工匠|案例、技巧與開發實戰》筆記的第 3 篇,你可以把它當作是一則重點整理,加上我個人的開發經驗與心得。
如第一篇所言,這是一本關於「Clean Code in Python」的書。
上一篇我整理書中了第 13 章「有關單元測試的建議」的內容(以及我的看法)。這次我們要再回到一開始,繼續學習如何寫好程式碼。
本文整理自書中的第 1 章第 3 節,為了不過度重複書中內容,下筆點到為止,並加上我自己的理解。
變數是程式碼中的基本元素,它們幾乎無所不在。
老實說,看這本書之前,我也想沒到,原來變數的使用有這麼多的學問!
以下就讓我們來一探究竟。
一、保持變數的一致性
這裡有兩種一致性:
- 名字一致性:在同一專案、模組、函式中,變數名稱應該保持一致。意思是,對「同一件事物」,不要用不同名稱。
- 型態一致性:變數的型態(型別)應該保持一致。意思是,不要把同一個變數,重新指向不同型態的資料。
老實說,這兩件事,就我的經驗,如果團隊沒有特別要求,那就一定會有人違反。
乍看這好像也沒什麼,但當你的程式碼規模變得越來越龐大,這些不一致就會變成隱藏的 bug——魔鬼真的藏在細節裡。
所幸 Mypy 不允許你變更變數型態,它的檢查確保了型態一致性。但命名上的一致性,只能靠人來保證。
關於「一致性」的議題,我們還會另篇討論——這真的非常重要。
重新把變數指向不同型態的資料
這真的是一個很常見的「巨大壞味道」。當你在程式碼中看到這樣的事情,就應該立刻警覺。
雖然許多時候它可能不會「真的」造成問題(所以才不受重視),但這樣的寫法會讓你的程式碼變得難以理解——為什麼前面是 list,後面卻變成了 dict?
而真正造成問題的時候,又很難 debug。
以前我也會做這種事,而且從 Python 語法角度,這「完全合法」呀!
後來自己被「坑」到以後,才理解這樣的寫法是多麼危險——難怪 Mypy 會禁止這樣的行為。
一個簡單避免這類行為的手段,就是重新命名一個新變數吧!還有安裝 Mypy,讓工具來幫你檢查。
二、變數宣告儘量靠近使用處
這是一個好習慣,也是讓程式碼更易讀的方法。
如果我還要跨越好幾百行才能找到一個變數是怎麼宣告的,那會讓人絕望。
當然幾百行是誇張了,但如果是長函式,然後變數宣告在函式的開頭,那至少也是幾十行的事——太累了。
我們希望變數的宣告與使用能夠愈近愈好。
這樣的好處是,你可以快速理解這個變數是幹嘛的,而不用一直往上找。
三、宣告「臨時變數」提升可讀性
我覺得這是平時開發中,非常容易忽略的一點——因為這很反人性!
當你在寫程式碼時,通常你會想到什麼就寫什麼,而不會去想到「這裡可以宣告一個臨時變數,讓程式碼更好讀」。
這真的很難XD
我們直接看書中的例子:
1 | # 為所有性別為女性,或者等級大於 3 的活躍使用者發放 10000 個金幣 |
因為直接照著「業務邏輯」寫,程式碼隨著業務邏輯的複雜度增加,變得難以閱讀。
此時,我們可以宣告一個「臨時變數」,讓程式碼更易讀:
1 | # 為所有性別為女性,或者等級大於 3 的活躍使用者發放 10000 個金幣 |
我覺得這真的堪稱神來一筆——這樣的寫法,讓程式碼更易讀,也更易維護。
你看完可能覺得,這好像也沒什麼,難嗎?
我覺得其中的難點在於:你恰好意識到,臨時變數在這個場景的必要性。
這需要很細微的心思,與為他人著想的精神。因為你自己寫、自己讀,其實不需要這麼麻煩。
我稱這樣的臨時變數為——良心事業!
四、能不宣告變數就別宣告
當然你看完上一條建議,決心想要好好適時宣告變數,當一個「貼心的人」的時候。
這條建議就是要防止你矯枉過正,濫用上述建議XD
這正是程式設計可以稱為「藝術」的地方——平衡。
定義臨時變數可以提高可讀性。但有時,把不必要的東西賦值成臨時變數反而會讓程式碼顯得囉嗦:
1 | def get_best_trip_by_user_id(user_id): |
其實,這段程式碼裡的三個臨時變數完全可以去掉,變成這樣:
1 | def get_best_trip_by_user_id(user_id): |
簡言之,變數是「我現在就需要」才宣告——包括臨時變數。
五、空行也是一種「註解」
說真的,我本來是打算把這段的標題作為文章標題,但這樣顯然有點「文不對題」。
空行是程式碼的一部分,它可以讓程式碼更易讀。
看看書上怎麼說:
程式碼裡的註解不只是那些常規的描述性語句,有時候,沒有一個字元的空行,也算得上一種特殊的「註解」。
在寫程式碼時,我們可以適當地在程式碼中插入空行,把程式碼按不同的邏輯塊分隔開,這樣能有效提升程式碼的可讀性。
這些道理大家都懂,但真正做到的人,可能還不算太多。
部分開發者對於「空行」的態度,還是比較隨心所欲,未必是著眼於程式碼的可讀。
因此讓人感覺缺乏一致性:相同的情況,有時候會空行,有時候又不會。
所以我才會很想把本段作為文章標題,來強調「空行」的重要性XD
相關文章