len(x)擊敗x.len(),從內置函數(shù)看Python的設計思想

內置函數(shù)是 Python 的一大特色,用極簡的語法實現(xiàn)很多常用的操作。

成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務,包含不限于網(wǎng)站設計制作、成都網(wǎng)站建設、齊齊哈爾網(wǎng)絡推廣、小程序定制開發(fā)、齊齊哈爾網(wǎng)絡營銷、齊齊哈爾企業(yè)策劃、齊齊哈爾品牌公關、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務,您的肯定,是我們最大的嘉獎;成都創(chuàng)新互聯(lián)公司為所有大學生創(chuàng)業(yè)者提供齊齊哈爾建站搭建服務,24小時服務熱線:18980820575,官方網(wǎng)址:bm7419.com

它們預先定義在內置命名空間中,開箱即用,所見即所得。Python 被公認是一種新手友好型的語言,這種說法能夠成立,內置函數(shù)在其中起到了極關鍵的作用。

舉個例子,求字符串 x 的長度,Python 的寫法是 len(x) ,而且這種寫法對列表、元組和字典等對象也同樣適用,只需要傳入對應的參數(shù)即可。len() 函數(shù)是共用的。

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

但是,有些語言并不是這樣,例如在 Java 中,字符串類有一個求長度的方法,其它類也有自己的求長度的方法,它們無法共用。每次使用時,通過類或實例來調用。

同樣是求字符串長度,Python 的寫法:

len(x) 擊敗 x.len(),從內置函數(shù)看 Python 的設計思想

而在 Java 中,寫法可能如下(簡化起見):

len(x) 擊敗 x.len(),從內置函數(shù)看 Python 的設計思想

Python 采用的是一種前綴表達式?,而 Java 采用的則是后綴表達式?。

除了求長度,Python 的某些內置函數(shù)也能在 Java 中找到對應的表達。例如,數(shù)值型字符串 s 轉化為整型數(shù)字,Python 可以用int(s)函數(shù),而 Java 可以用?Integer.parseInt(s);整型數(shù)字轉化為字符串,Python 可以用str(i),而 Java 也有String.valueOf(i)。

Python 的內置函數(shù)不與特定的類綁定,它們是一級對象。而 Java 的“函數(shù)”則無法脫離類而存在,它們只是附屬品。

從直觀角度來看,Python 的表達似乎是更優(yōu)的。但是,它們并不具有可比性?,因為這是兩套語言系統(tǒng),各有獨特的范疇背景,并不能輕易地化約。

就好比是,不能因為拉丁字母筆畫簡單,就說它優(yōu)于漢字,因為在表意時,字母(表音文字)是遠遜于漢字(表意文字)的。同樣的,日本借用了漢字的偏旁部首而造出來的文字,雖然更省筆墨,但是也完全喪失了意蘊。

以此類比,Python 的內置函數(shù)雖有簡便之美,但卻丟失了某些表意功能。有些人在質疑/抨擊 Python 的時候,也喜歡拿這點說事,認為這是 Python 的設計缺陷。

這就引出本文最想討論的一個問題來:為什么 Python 要設計成 len(x) 這種前綴表達,而不是 x.len() 這樣的后綴表達呢?

事實上,后綴設計也是可行的,以 Python 中列表的兩個方法為例:

len(x) 擊敗 x.len(),從內置函數(shù)看 Python 的設計思想

它們都是通過列表對象來調用,并不是憑空從內置命名空間中拿來的。語義表達得也很清楚,就是對 mylist 做排序和逆轉。

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

len(x) 擊敗 x.len(),從內置函數(shù)看 Python 的設計思想

不同的寫法,都在做同一件事(不考慮它們的副作用)。因此,后綴語法并非不可行,之所以不用,那肯定是刻意的設計。

回到前面的問題:為什么是 len(x) ,而非 x.len(x),這源于 Python 的什么設計思想呢?

Python 之父?Guido van Rossum?曾經(jīng)解釋過這個問題(鏈接見文末),有兩個原因:

對于某些操作,前綴符比后綴更好讀——前綴(和中綴)表示法在數(shù)學中有著悠久的歷史,其視覺效果有助于數(shù)學家思考問題。我們可以簡單地把公式?x*(a + b)?重寫成x*a + x*b?,但同樣的事,以原生的面向對象的方式實現(xiàn),就比較笨拙。

當讀到 len(x) 時,我就?知道?這是在求某對象的長度。它告訴我了兩點:返回值是一個整數(shù),參數(shù)是某種容器。但當讀到 x.len() 時,我必須事先知道某種容器 x,它實現(xiàn)了一個接口,或者繼承了一個擁有標準 len() 方法的類。我們經(jīng)常會目睹到這種混亂:一個類并沒有實現(xiàn)映射(mapping)接口,卻擁有 get() 或 keys() 方法,或者某些非文件對象,卻擁有一個 write() 方法。

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

這就好比說,分數(shù)???中的橫線是數(shù)學中的一個“內置”表達式,并不需要再實現(xiàn)什么接口之類的,它自身已經(jīng)表明了“某數(shù)除以某數(shù)?”的意思。不同類型的數(shù)(整數(shù)、浮點數(shù)、有理數(shù)、無理數(shù)…)共用同一個操作符,不必為每類數(shù)據(jù)實現(xiàn)一種求分數(shù)的操作。

優(yōu)雅易懂是 Python 奉行的設計哲學?,len() 函數(shù)的前綴表達方式是最好的體現(xiàn)。我曾引述過 Guido 對“為什么索引從 0 開始?”的解釋。其最重要的原因,也正是 0-based 索引最優(yōu)雅易懂。

讓我們來先看看切片的用法。可能最常見的用法,就是“取前 n 位元素”或“從第i 位索引起,取后 n 位元素”(前一種用法,實際上是 i == 起始位的特殊用法)。如果這兩種用法實現(xiàn)時可以不在表達式中出現(xiàn)難看的 +1 或 -1,那將會非常的優(yōu)雅。

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

所以,我們能說 len(x) 擊敗 x.len() ,支撐它的是一種化繁為簡、純粹卻深邃的設計思想。

面向對象的編程語言自發(fā)明時起,就想模擬我們生活于其中的現(xiàn)實世界??墒鞘裁搭惏?、接口啊、對象啊、以及它們的方法啊,這些玩意的毒,有時候蒙蔽了我們去看見世界本質的眼睛。

桌子類有桌子類的求長度方法,椅子類有椅子類的求長度方法,無窮無盡,可現(xiàn)實真是如此么?求長度的方法就不能是一種獨立存在的對象么?它之所以存在,是因為有“對象”存在,而不是因為有某個類才存在啊。

所以,我想說,len(x) 擊敗 x.len(),這還體現(xiàn)了?Python 對世界本質的洞察?。

求某個對象的長度,這種操作獨立于對象之外而存在,并不是該對象內部所有的一種屬性或功能。從這個角度理解,我們能夠明白,為什么 Python 要設計出內置函數(shù)??內置函數(shù)其實是對世界本質的一種捕捉。

這些見微知著的發(fā)現(xiàn),足夠使我們愛上這門語言了。人生苦短,我用 Python。

關聯(lián)閱讀:

Guido 解釋 len 的由來:http://suo.im/4ImAEo

Guido 解釋 0 索引的由來:http://suo.im/5cr12S

分享文章:len(x)擊敗x.len(),從內置函數(shù)看Python的設計思想
本文網(wǎng)址:http://bm7419.com/article0/jcehio.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供ChatGPT、外貿建站網(wǎng)站營銷、網(wǎng)站改版小程序開發(fā)、做網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設