Python 代碼一致性的重要性
本文是 Python 之禪特殊系列的一部分,重點(diǎn)是第十二、十三和十四原則:模糊性和明確性的作用。
最小驚喜原則是設(shè)計(jì)用戶界面時(shí)的一個(gè) 準(zhǔn)則。它是說(shuō),當(dāng)用戶執(zhí)行某項(xiàng)操作時(shí),程序執(zhí)行的事情應(yīng)該使用戶盡量少地感到意外。這和孩子們喜歡一遍又一遍地讀同一本書的原因是一樣的:沒有什么比能夠預(yù)測(cè)并讓預(yù)測(cè)成真更讓人欣慰的了。
在開發(fā) ABC 語(yǔ)言(Python 的靈感來(lái)源)的過程中,一個(gè)重要的見解是,編程設(shè)計(jì)是用戶界面,需要使用與 UI 設(shè)計(jì)者相同的工具來(lái)設(shè)計(jì)。值得慶幸的是,從那以后,越來(lái)越多的語(yǔ)言采用了 UI 設(shè)計(jì)中的可承受性和人體工程學(xué)的概念,即使它們的應(yīng)用并不嚴(yán)格。
這就引出了 Python 之禪 中的三個(gè)原則。
面對(duì)歧義,要拒絕猜測(cè)的誘惑
1 + "1"
的結(jié)果應(yīng)該是什么? "11"
和 2
都是猜測(cè)。這種表達(dá)方式是歧義的:無(wú)論如何做都會(huì)讓一些人感到驚訝。
一些語(yǔ)言選擇猜測(cè)。在 JavaScript 中,結(jié)果為 "11"
。在 Perl 中,結(jié)果為 2
。在 C 語(yǔ)言中,結(jié)果自然是空字符串。面對(duì)歧義,JavaScript、Perl 和 C 都在猜測(cè)。
在 Python 中,這會(huì)引發(fā) TypeError
:這不是能忽略的錯(cuò)誤。捕獲 TypeError
是非典型的:它通常將終止程序或至少終止當(dāng)前任務(wù)(例如,在大多數(shù) Web 框架中,它將終止對(duì)當(dāng)前請(qǐng)求的處理)。
Python 拒絕猜測(cè) 1 + "1"
的含義。程序員必須以明確的意圖編寫代碼:1 + int("1")
,即 2
;或者 str(1) + "1"
,即 "11"
;或 "1"[1:]
,這將是一個(gè)空字符串。通過拒絕猜測(cè),Python 使程序更具可預(yù)測(cè)性。
盡量找一種,最好是唯一一種明顯的解決方案
預(yù)測(cè)也會(huì)出現(xiàn)偏差。給定一個(gè)任務(wù),你能預(yù)知要實(shí)現(xiàn)該任務(wù)的代碼嗎?當(dāng)然,不可能完美地預(yù)測(cè)。畢竟,編程是一項(xiàng)具有創(chuàng)造性的任務(wù)。
但是,不必有意提供多種冗余方式來(lái)實(shí)現(xiàn)同一目標(biāo)。從某種意義上說(shuō),某些解決方案或許 “更好” 或 “更 Python 化”。
對(duì) Python 美學(xué)欣賞部分是因?yàn)?,可以就哪種解決方案更好進(jìn)行健康的辯論。甚至可以持不同觀點(diǎn)而繼續(xù)編程。甚至為使其達(dá)成一致,接受不同意的觀點(diǎn)也是可以的。但在這一切之下,必須有一種這樣的認(rèn)識(shí),即正確的解決方案終將會(huì)出現(xiàn)。我們必須希望,通過商定實(shí)現(xiàn)目標(biāo)的最佳方法,而最終達(dá)成真正的一致。
雖然這種方式一開始可能并不明顯(除非你是荷蘭人)
這是一個(gè)重要的警告:首先,實(shí)現(xiàn)任務(wù)的最佳方法往往不明顯。觀念在不斷發(fā)展。Python 也在進(jìn)化。逐塊讀取文件的最好方法,可能要等到 Python 3.8 時(shí)使用 walrus 運(yùn)算符(:=
)。
逐塊讀取文件這樣常見的任務(wù),在 Python 存在近 30年 的歷史中并沒有 “唯一的最佳方法”。
當(dāng)我在 1998 年從 Python 1.5.2 開始使用 Python 時(shí),沒有一種逐行讀取文件的最佳方法。多年來(lái),知道字典中是否有某個(gè)鍵的最佳方法是使用關(guān)鍵字 .haskey
,直到 in
操作符出現(xiàn)才發(fā)生改變。
只是要意識(shí)到找到實(shí)現(xiàn)目標(biāo)的一種(也是唯一一種)方法可能需要 30 年的時(shí)間來(lái)嘗試其它方法,Python 才可以不斷尋找這些方法。這種歷史觀認(rèn)為,為了做一件事用上 30 年是可以接受的,但對(duì)于美國(guó)這個(gè)存在僅 200 多年的國(guó)家來(lái)說(shuō),人們常常會(huì)感到不習(xí)慣。
從 Python 之禪的這一部分來(lái)看,荷蘭人,無(wú)論是 Python 的創(chuàng)造者 Guido van Rossum 還是著名的計(jì)算機(jī)科學(xué)家 Edsger W. Dijkstra,他們的世界觀是不同的。要理解這一部分,某種程度的歐洲人對(duì)時(shí)間的感受是必不可少的。