len(x) 擊敗 x.len()小腊,從內(nèi)置函數(shù)看 Python 的設(shè)計(jì)思想

image

內(nèi)置函數(shù)是 Python 的一大特色,用極簡(jiǎn)的語(yǔ)法實(shí)現(xiàn)很多常用的操作久窟。

它們預(yù)先定義在內(nèi)置命名空間中秩冈,開(kāi)箱即用,所見(jiàn)即所得斥扛。Python 被公認(rèn)是一種新手友好型的語(yǔ)言入问,這種說(shuō)法能夠成立,內(nèi)置函數(shù)在其中起到了極關(guān)鍵的作用稀颁。

舉個(gè)例子芬失,求字符串 x 的長(zhǎng)度,Python 的寫(xiě)法是 len(x) 匾灶,而且這種寫(xiě)法對(duì)列表棱烂、元組和字典等對(duì)象也同樣適用,只需要傳入對(duì)應(yīng)的參數(shù)即可阶女。len() 函數(shù)是共用的颊糜。

這是一種極簡(jiǎn)哲學(xué)的體現(xiàn):Simple is better than complex。

但是秃踩,有些語(yǔ)言并不是這樣衬鱼,例如在 Java 中,字符串類(lèi)有一個(gè)求長(zhǎng)度的方法憔杨,其它類(lèi)也有自己的求長(zhǎng)度的方法馁启,它們無(wú)法共用。每次使用時(shí)芍秆,通過(guò)類(lèi)或?qū)嵗齺?lái)調(diào)用惯疙。

同樣是求字符串長(zhǎng)度,Python 的寫(xiě)法:

saying = "Hello world!"
print(len(saying))

# 結(jié)果:12

而在 Java 中妖啥,寫(xiě)法可能如下(簡(jiǎn)化起見(jiàn)):

String saying = "Hello world!";
System.out.println(saying.length());

// 結(jié)果:12

Python 采用的是一種前綴表達(dá)式 霉颠,而 Java 采用的則是后綴表達(dá)式

除了求長(zhǎng)度荆虱,Python 的某些內(nèi)置函數(shù)也能在 Java 中找到對(duì)應(yīng)的表達(dá)蒿偎。例如,數(shù)值型字符串 s 轉(zhuǎn)化為整型數(shù)字怀读,Python 可以用 int(s) 函數(shù)诉位,而 Java 可以用 Integer.parseInt(s) ;整型數(shù)字轉(zhuǎn)化為字符串菜枷,Python 可以用 str(i) 苍糠,而 Java 也有 String.valueOf(i)

Python 的內(nèi)置函數(shù)不與特定的類(lèi)綁定啤誊,它們是一級(jí)對(duì)象岳瞭。而 Java 的“函數(shù)”則無(wú)法脫離類(lèi)而存在拥娄,它們只是附屬品。

從直觀角度來(lái)看瞳筏,Python 的表達(dá)似乎是更優(yōu)的稚瘾。但是,它們并不具有可比性 姚炕,因?yàn)檫@是兩套語(yǔ)言系統(tǒng)摊欠,各有獨(dú)特的范疇背景,并不能輕易地化約柱宦。

就好比是凄硼,不能因?yàn)槔∽帜腹P畫(huà)簡(jiǎn)單,就說(shuō)它優(yōu)于漢字捷沸,因?yàn)樵诒硪鈺r(shí)摊沉,字母(表音文字)是遠(yuǎn)遜于漢字(表意文字)的。同樣的痒给,日本借用了漢字的偏旁部首而造出來(lái)的文字说墨,雖然更省筆墨,但是也完全喪失了意蘊(yùn)苍柏。

以此類(lèi)比尼斧,Python 的內(nèi)置函數(shù)雖有簡(jiǎn)便之美,但卻丟失了某些表意功能试吁。有些人在質(zhì)疑/抨擊 Python 的時(shí)候棺棵,也喜歡拿這點(diǎn)說(shuō)事,認(rèn)為這是 Python 的設(shè)計(jì)缺陷熄捍。

這就引出本文最想討論的一個(gè)問(wèn)題來(lái):為什么 Python 要設(shè)計(jì)成 len(x) 這種前綴表達(dá)烛恤,而不是 x.len() 這樣的后綴表達(dá)呢?

事實(shí)上余耽,后綴設(shè)計(jì)也是可行的缚柏,以 Python 中列表的兩個(gè)方法為例:

mylist = [2, 1, 3, 5, 4]

mylist.sort()
print(mylist)   # [1, 2, 3, 4, 5]

mylist.reverse()
print(mylist)   # [5, 4, 3, 2, 1]

它們都是通過(guò)列表對(duì)象來(lái)調(diào)用,并不是憑空從內(nèi)置命名空間中拿來(lái)的碟贾。語(yǔ)義表達(dá)得也很清楚币喧,就是對(duì) mylist 做排序和逆轉(zhuǎn)。

恰恰那么巧袱耽,它們還有兩個(gè)同父異母的兄弟 sorted() 與 reversed()杀餐,這倆是前綴表達(dá)型。

mylist = [2, 1, 3, 5, 4]

sort_list = sorted(mylist)
print(sort_list)   # [1, 2, 3, 4, 5]

reverse_list = reversed(mylist)
print(list(reverse_list))   # [4, 5, 3, 1, 2]

不同的寫(xiě)法朱巨,都在做同一件事(不考慮它們的副作用)史翘。因此,后綴語(yǔ)法并非不可行,之所以不用恶座,那肯定是刻意的設(shè)計(jì)。

回到前面的問(wèn)題:為什么是 len(x) 沥阳,而不是 x.len(x)跨琳,這根源于 Python 的什么設(shè)計(jì)思想呢?

Python 之父 Guido van Rossum 曾經(jīng)解釋過(guò)這個(gè)問(wèn)題(鏈接見(jiàn)文末)桐罕,有兩個(gè)原因:

  • 對(duì)于某些操作脉让,前綴符比后綴更好讀——前綴(和中綴)表示法在數(shù)學(xué)中有著悠久的歷史,其視覺(jué)效果有助于數(shù)學(xué)家思考問(wèn)題功炮。我們可以簡(jiǎn)單地把公式 x*(a + b) 重寫(xiě)成 x*a + x*b 溅潜,但同樣的事,以原生的面向?qū)ο蟮姆绞綄?shí)現(xiàn)薪伏,就比較笨拙滚澜。
  • 當(dāng)讀到 len(x) 時(shí),我就 知道 這是在求某對(duì)象的長(zhǎng)度嫁怀。它告訴我了兩點(diǎn):返回值是一個(gè)整數(shù)设捐,參數(shù)是某種容器。但當(dāng)讀到 x.len() 時(shí)塘淑,我必須事先知道某種容器 x萝招,它實(shí)現(xiàn)了一個(gè)接口,或者繼承了一個(gè)擁有標(biāo)準(zhǔn) len() 方法的類(lèi)存捺。我們經(jīng)常會(huì)目睹到這種混亂:一個(gè)類(lèi)并沒(méi)有實(shí)現(xiàn)映射(mapping)接口槐沼,卻擁有 get() 或 keys() 方法,或者某些非文件對(duì)象捌治,卻擁有一個(gè) write() 方法岗钩。

解釋完這兩個(gè)原因之后,Guido 還總結(jié)成一句話(huà)說(shuō):“I see 'len' as a built-in operation ”肖油。這已經(jīng)不僅是在說(shuō) len() 更可讀易懂了凹嘲,而完全是在拔高 len() 的地位。

這就好比說(shuō)构韵,分?jǐn)?shù) ? 中的橫線(xiàn)是數(shù)學(xué)中的一個(gè)“內(nèi)置”表達(dá)式周蹭,并不需要再實(shí)現(xiàn)什么接口之類(lèi)的,它自身已經(jīng)表明了“某數(shù)除以某數(shù) ”的意思疲恢。不同類(lèi)型的數(shù)(整數(shù)凶朗、浮點(diǎn)數(shù)、有理數(shù)显拳、無(wú)理數(shù)...)共用同一個(gè)操作符棚愤,不必為每類(lèi)數(shù)據(jù)實(shí)現(xiàn)一種求分?jǐn)?shù)的操作。

優(yōu)雅易懂是 Python 奉行的設(shè)計(jì)哲學(xué) ,len() 函數(shù)的前綴表達(dá)方式是最好的體現(xiàn)宛畦。我想起在《超強(qiáng)匯總:學(xué)習(xí)Python列表瘸洛,只需這篇文章就夠了》這篇文章中,曾引述過(guò) Guido 對(duì)“為什么索引從 0 開(kāi)始 ”的解釋次和。其最重要的原因反肋,也正是 0-based 索引最優(yōu)雅易懂。

讓我們來(lái)先看看切片的用法踏施∈幔可能最常見(jiàn)的用法,就是“取前 n 位元素”或“從第i 位索引起畅形,取后 n 位元素”(前一種用法养距,實(shí)際上是 i == 起始位的特殊用法)。如果這兩種用法實(shí)現(xiàn)時(shí)可以不在表達(dá)式中出現(xiàn)難看的 +1 或 -1日熬,那將會(huì)非常的優(yōu)雅幌羞。

使用 0-based 的索引方式瓶珊、半開(kāi)區(qū)間切片和缺省匹配區(qū)間的話(huà)(Python最終采用這樣的方式),上面兩種情形的切片語(yǔ)法就變得非常漂亮:a[:n] 和 a[i:i+n],前者是 a[0:n] 的縮略寫(xiě)法巾陕。

所以怠缸,我們能說(shuō) len(x) 擊敗 x.len() 睁蕾,支撐它的是一種化繁為簡(jiǎn)秕狰、純粹卻深邃的設(shè)計(jì)思想。

面向?qū)ο蟮木幊陶Z(yǔ)言自發(fā)明時(shí)起东跪,就想模擬我們生活于其中的現(xiàn)實(shí)世界畸陡。可是什么類(lèi)啊虽填、接口啊丁恭、對(duì)象啊、以及它們的方法啊斋日,這些玩意的毒牲览,有時(shí)候蒙蔽了我們?nèi)タ匆?jiàn)世界本質(zhì)的眼睛。

桌子類(lèi)有桌子類(lèi)的求長(zhǎng)度方法恶守,椅子類(lèi)有椅子類(lèi)的求長(zhǎng)度方法第献,無(wú)窮無(wú)盡,可現(xiàn)實(shí)真是如此么兔港?求長(zhǎng)度的方法就不能是一種獨(dú)立存在的對(duì)象么庸毫?它之所以存在,是因?yàn)橛小皩?duì)象”存在衫樊,而不是因?yàn)橛心硞€(gè)類(lèi)才存在啊飒赃。

所以利花,我想說(shuō),len(x) 擊敗 x.len()载佳,這還體現(xiàn)了 Python 對(duì)世界本質(zhì)的洞察 炒事。

求某個(gè)對(duì)象的長(zhǎng)度,這種操作獨(dú)立于對(duì)象之外而存在蔫慧,并不是該對(duì)象內(nèi)部所有的一種屬性或功能挠乳。從這個(gè)角度理解,我們能夠明白藕漱,為什么 Python 要設(shè)計(jì)出內(nèi)置函數(shù)欲侮? 內(nèi)置函數(shù)其實(shí)是對(duì)世界本質(zhì)的一種捕捉崭闲。

這些見(jiàn)微知著的發(fā)現(xiàn)肋联,足夠使我們愛(ài)上這門(mén)語(yǔ)言了。人生苦短刁俭,我用 Python橄仍。

關(guān)聯(lián)閱讀:

Guido 解釋 len 的由來(lái):http://suo.im/4ImAEo

Guido 解釋 0 索引的由來(lái):http://suo.im/5cr12S

本文原創(chuàng)并首發(fā)于公眾號(hào)【Python貓】,未經(jīng)授權(quán)牍戚,請(qǐng)勿轉(zhuǎn)載侮繁。

原文地址:https://mp.weixin.qq.com/s/pKQT5wvyaSNFvnJexiCC8w

image

公眾號(hào)【Python貓】, 本號(hào)連載優(yōu)質(zhì)的系列文章如孝,有喵星哲學(xué)貓系列宪哩、Python進(jìn)階系列、好書(shū)推薦系列第晰、技術(shù)寫(xiě)作锁孟、優(yōu)質(zhì)英文推薦與翻譯等等,歡迎關(guān)注哦茁瘦。后臺(tái)回復(fù)“愛(ài)學(xué)習(xí)”品抽,免費(fèi)獲得一份學(xué)習(xí)大禮包。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末甜熔,一起剝皮案震驚了整個(gè)濱河市圆恤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌腔稀,老刑警劉巖盆昙,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異焊虏,居然都是意外死亡弱左,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)炕淮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)拆火,“玉大人,你說(shuō)我怎么就攤上這事∶蔷担” “怎么了币叹?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)模狭。 經(jīng)常有香客問(wèn)我颈抚,道長(zhǎng),這世上最難降的妖魔是什么嚼鹉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任贩汉,我火速辦了婚禮,結(jié)果婚禮上锚赤,老公的妹妹穿的比我還像新娘匹舞。我一直安慰自己,他們只是感情好线脚,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布赐稽。 她就那樣靜靜地躺著,像睡著了一般浑侥。 火紅的嫁衣襯著肌膚如雪姊舵。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天寓落,我揣著相機(jī)與錄音括丁,去河邊找鬼。 笑死伶选,一個(gè)胖子當(dāng)著我的面吹牛史飞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播考蕾,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼祸憋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了肖卧?” 一聲冷哼從身側(cè)響起蚯窥,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎塞帐,沒(méi)想到半個(gè)月后拦赠,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡葵姥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年荷鼠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片榔幸。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡允乐,死狀恐怖矮嫉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情牍疏,我是刑警寧澤蠢笋,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站鳞陨,受9級(jí)特大地震影響昨寞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厦滤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一援岩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧掏导,春花似錦享怀、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)限寞。三九已至忍啸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間履植,已是汗流浹背计雌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留玫霎,地道東北人凿滤。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像庶近,于是被迫代替她去往敵國(guó)和親翁脆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 一鼻种、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 5,748評(píng)論 0 10
  • 內(nèi)置函數(shù)Python解釋器內(nèi)置了許多功能和類(lèi)型,總是可用的反番。他們是按字母順序列在這里。 abs(x)返回一個(gè)數(shù)的絕...
    uangianlap閱讀 1,243評(píng)論 0 0
  • http://python.jobbole.com/85231/ 關(guān)于專(zhuān)業(yè)技能寫(xiě)完項(xiàng)目接著寫(xiě)寫(xiě)一名3年工作經(jīng)驗(yàn)的J...
    燕京博士閱讀 7,583評(píng)論 1 118
  • 她叉钥,一笑之后罢缸,成了千古罪人, 他投队,一怒之下枫疆,滅亡了一個(gè)朝代。 (一)敷鸦,浣衣清溪 清溪村因靠近清溪而得名息楔,而她就出生...
    輕與閱讀 352評(píng)論 0 4
  • 初中時(shí)值依,整個(gè)年級(jí)1.5k人兔甘,可以排到前50名,班級(jí)前幾名鳞滨。都說(shuō)一白遮百丑洞焙,學(xué)生時(shí)代是成績(jī)好,一切都好拯啦。度過(guò)了同學(xué)擁...
    嘉桐小鎮(zhèn)閱讀 980評(píng)論 0 5