編程某種意義上是一門『手藝』庇忌,因?yàn)閮?yōu)雅而高效的代碼义屏,就如同完美的手工藝品一樣讓人賞心悅目靠汁。
致“匠人”
在雕琢代碼的過程中,有大工程:比如應(yīng)該用什么架構(gòu)闽铐、哪種設(shè)計(jì)模式蝶怔。也有更多的小細(xì)節(jié),比如何時使用異常(Exceptions)兄墅、或怎么給變量起名踢星。那些真正優(yōu)秀的代碼,正是由無數(shù)優(yōu)秀的細(xì)節(jié)造就的隙咸。
『Python 工匠』這個系列文章沐悦,是作者的一次小小嘗試。它專注于分享 Python 編程中的一些偏『小』的東西五督。希望能夠幫到每一位編程路上的匠人藏否。
變量和代碼質(zhì)量
作為『Python 工匠』系列文章的第一篇,想先談?wù)勛兞浚╒ariables)充包。因?yàn)槿绾味x和使用變量副签,一直都是學(xué)習(xí)任何一門編程語言最先要掌握的技能之一遥椿。
變量用的好或不好,和代碼質(zhì)量有著非常重要的聯(lián)系淆储。在關(guān)于變量的諸多問題中冠场,為變量起一個好名字尤其重要。
如何為變量起名
在計(jì)算機(jī)科學(xué)領(lǐng)域本砰,有一句著名的格言(俏皮話):
There are only two hard things in Computer Science: cache invalidation and naming things.
在計(jì)算機(jī)科學(xué)領(lǐng)域只有兩件難事:緩存過期 和 給東西起名字碴裙。-- Phil Karlton
第一個『緩存過期問題』的難度不用多說,任何用過緩存的人都會懂点额。至于第二個『給東西起名字』這事的難度舔株,作者也是深有體會。在作者的職業(yè)生涯里咖楣,度過的作為黑暗的下午之一督笆,就是坐在顯示器前抓耳撓腮為一個新項(xiàng)目起一個合適的名字。
編程時起的最多的名字诱贿,還數(shù)各種變量娃肿。給變量起一個好名字很重要,因?yàn)楹玫淖兞棵梢詷O大提高代碼的整體可讀性珠十。
下面幾點(diǎn)料扰,是作者總結(jié)的為變量起名時,最好遵守的基本原則焙蹭。
1. 變量名要有描述性晒杈,不能太寬泛
在可接受的長度范圍內(nèi),變量名能把它所指向的內(nèi)容描述的越精確越好孔厉。所以拯钻,盡量不要用那些過于寬泛的詞來作為你的變量名:
· BAD: day, host, cards, temp
· GOOD: day_of_week, hosts_to_reboot, expired_cards
2. 變量名最好讓人能猜出類型
所有學(xué)習(xí) Python 的人都知道,Python 是一門動態(tài)類型語言撰豺,它(至少在 PEP 484 出現(xiàn)前)沒有變量類型聲明粪般。所以當(dāng)你看到一個變量時,除了通過上下文猜測污桦,沒法輕易知道它是什么類型亩歹。
不過,人們對于變量名和變量類型的關(guān)系凡橱,通常會有一些直覺上的約定小作,作者把它們總結(jié)在了下面。
什么樣的名字會被當(dāng)成 bool 類型稼钩?
布爾類型變量的最大特點(diǎn)是:它只存在兩個可能的值『是』 或 『不是』顾稀。所以,用 is坝撑、has 等非黑即白的詞修飾的變量名础拨,會是個不錯的選擇氮块。原則就是:讓讀到變量名的人覺得這個變量只會有『是』或『不是』兩種值。
下面是幾個不錯的示例:
· is_superuser:『是否超級用戶』诡宗,只會有兩種值:是/不是
· has_error:『有沒有錯誤』,只會有兩種值:有/沒有
· allow_vip:『是否允許 VIP』击儡,只會有兩種值:允許/不允許
· use_msgpack:『是否使用 msgpack』塔沃,只會有兩種值:使用/不使用
· debug:『是否開啟調(diào)試模式』,被當(dāng)做 bool 主要是因?yàn)榧s定俗成
什么樣的名字會被當(dāng)成 int/float 類型阳谍?
人們看到和數(shù)字相關(guān)的名字蛀柴,都會默認(rèn)他們是 int/float 類型,下面這些是比較常見的:
· 釋義為數(shù)字的所有單詞矫夯,比如:port(端口號)鸽疾、age(年齡)、radius(半徑) 等等
· 使用 _id 結(jié)尾的單詞训貌,比如:user_id制肮、host_id
·使用 length/count 開頭或者結(jié)尾的單詞,比如:length_of_username递沪、max_length豺鼻、users_count
注意:不要使用普通的復(fù)數(shù)來表示一個 int 類型變量,比如 apples款慨、trips儒飒,最好用 number_of_apples、trips_count 來替代檩奠。
其他類型:
對于 str桩了、list、tuple埠戳、dict 這些復(fù)雜類型井誉,很難有一個統(tǒng)一的規(guī)則讓我們可以通過名字去猜測變量類型。比如 headers乞而,既可能是一個頭信息列表送悔,也可能是包含頭信息的 dict。
對于這些類型的變量名爪模,最推薦的方式欠啤,就是編寫規(guī)范的文檔,在函數(shù)和方法的 document string 中屋灌,使用 sphinx 格式(Python 官方文檔使用的文檔工具)來標(biāo)注所有變量的類型洁段。
3. 適當(dāng)使用『匈牙利命名法』
第一次知道『匈牙利命名法』,是在 Joel on Software 的一篇博文中共郭。簡而言之祠丝,匈牙利命名法就是把變量的『類型』縮寫疾呻,放到變量名的最前面。
關(guān)鍵在于写半,這里說的變量『類型』岸蜗,并非指傳統(tǒng)意義上的 int/str/list 這種類型,而是指那些和你的代碼業(yè)務(wù)邏輯相關(guān)的類型叠蝇。
比如璃岳,在你的代碼中有兩個變量:students 和 teachers,他們指向的內(nèi)容都是一個包含 Person 對象的 list 悔捶。使用『匈牙利命名法』后铃慷,可以把這兩個名字改寫成這樣:
students -> pl_students
teachers -> pl_teachers
其中 pl 是 person list 的首字母縮寫。當(dāng)變量名被加上前綴后蜕该,如果你看到以 pl_ 打頭的變量犁柜,就能知道它所指向的值類型了。
很多情況下堂淡,使用『匈牙利命名法』是個不錯的主意馋缅,因?yàn)樗梢愿纳颇愕拇a可讀性,尤其在那些變量眾多淤齐、同一類型多次出現(xiàn)時股囊。注意不要濫用就好。
4. 變量名盡量短更啄,但是絕對不要太短
在前面稚疹,我們提到要讓變量名有描述性。如果不給這條原則加上任何限制祭务,那么你很有可能寫出這種描述性極強(qiáng)的變量名:how_much_points_need_for_level2内狗。如果代碼中充斥著這種過長的變量名,對于代碼可讀性來說是個災(zāi)難义锥。
一個好的變量名柳沙,長度應(yīng)該控制在兩到三個單詞左右。比如上面的名字拌倍,可以縮寫為 points_level2赂鲤。
絕大多數(shù)情況下,都應(yīng)該避免使用那些只有一兩個字母的短名字柱恤,比如數(shù)組索引三劍客 i数初、j、k梗顺,用有明確含義的名字泡孩,比如 persion_index 來代替它們總是會更好一些。
使用短名字的例外情況:
有時寺谤,上面的原則也存在一些例外仑鸥。當(dāng)一些意義明確但是較長的變量名重復(fù)出現(xiàn)時吮播,為了讓代碼更簡潔,使用短名字縮寫是完全可以的眼俊。但是為了降低理解成本意狠,同一段代碼內(nèi)最好不要使用太多這種短名字。
比如在 Python 中導(dǎo)入模塊時疮胖,就會經(jīng)常用到短名字作為別名摄职,像 Django i18n 翻譯時常用的 gettext 方法通常會被縮寫成 _ 來使用(from django.utils.translation import ugettext as _)
5. 其他注意事項(xiàng)
其他一些給變量命名的注意事項(xiàng):
· 同一段代碼內(nèi)不要使用過于相似的變量名,比如同時出現(xiàn) users获列、users1、 user3 這種序列
· 不要使用帶否定含義的變量名蛔垢,用 is_special 代替 is_not_normal
結(jié)束語
碎碎念了一大堆击孩,不知道有多少人能夠堅(jiān)持到最后。變量作為程序語言的重要組成部分鹏漆,值得我們在定義和使用它時巩梢,多花一丁點(diǎn)時間思考一下,那樣會讓你的代碼變得更優(yōu)秀艺玲。
下周將為大家介紹如何更好地使用變量括蝠。
原文作者:騰訊高級工程師 朱雷
來源:騰訊內(nèi)部KM論壇