真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Python是強類型語言還是弱類型語言

本篇內(nèi)容主要講解“Python是強類型語言還是弱類型語言”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“Python是強類型語言還是弱類型語言”吧!

成都創(chuàng)新互聯(lián)專注于輪臺網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供輪臺營銷型網(wǎng)站建設(shè),輪臺網(wǎng)站制作、輪臺網(wǎng)頁設(shè)計、輪臺網(wǎng)站官網(wǎng)定制、微信小程序定制開發(fā)服務(wù),打造輪臺網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供輪臺網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

1、動靜類型與強弱類型

很多讀者應(yīng)該都熟悉動態(tài)類型與靜態(tài)類型,但是很多人也會把它們跟強弱類型混為一談,所以我們有必要先作一下概念上的澄清。

這兩組類型都是針對于編程語言而言的,但關(guān)注的核心問題不同。

對于“動靜類型”概念,它的核心問題是“什么時候知道一個變量是哪種類型”?

一般而言,在編譯期就確定變量類型的是靜態(tài)類型語言,在運行期才確定變量類型的則是動態(tài)類型語言。

例如,某些語言中定義函數(shù)“int func(int a){…}”,在編譯時就能確定知道它的參數(shù)和返回值是 int 類型,所以是靜態(tài)類型;而典型如  Python,定義函數(shù)時寫“def func(a):…”,并不知道參數(shù)和返回值的類型,只有到運行時調(diào)用函數(shù),才最終確定參數(shù)和返回值的類型,所以是動態(tài)類型

對于“強弱類型”概念,它的核心問題是“不同類型的變量是否允許隱式轉(zhuǎn)化”?

一般而言,編譯器有很少(合理)隱式類型轉(zhuǎn)化的是強類型語言,有較多(過分)隱式類型轉(zhuǎn)化的是弱類型語言。

例如,Javascript 中的 "1000"+1會得到字符串“10001”,而 "1000"-1則會得到數(shù)字  999,也就是說,編譯器根據(jù)使用場合,對兩種不同類型的對象分別做了隱式的類型轉(zhuǎn)化,但是相似的寫法,在強類型語言中則會報類型出錯。(數(shù)字與字符串的轉(zhuǎn)化屬于過分的轉(zhuǎn)化,下文會再提到一些合理的轉(zhuǎn)化。)

按照以上的定義,有人將常見的編程語言畫了一張分類圖:

Python是強類型語言還是弱類型語言

按強弱類型維度劃分,可以歸納出:

  • 強類型:Java、C#、Python、Ruby、Erlang(再加GO、Rust)……

  • 弱類型:C、C++、Javascript、Perl、PHP、VB……

2、過去的強弱類型概念

動靜類型的概念基本上被大家所認(rèn)可,然而,強弱類型的概念在問答社區(qū)、技術(shù)論壇和學(xué)術(shù)討論上卻有很多的爭議。此處就不作羅列了。

為什么會有那么多爭議呢?

最主要的原因之一是有人把它與動靜類型混用了。

最明顯的一個例子就是 Guido van Rossum 在 2003 年參加的一個訪談,它的話題恰好是關(guān)于強弱類型的(Strong versus Weak  Typing):

Python是強類型語言還是弱類型語言

但是,他們談?wù)摰拿黠@只是動靜類型的區(qū)別。

訪談中還引述了 Java 之父 James Gosling 的話,從他的表述中也能看出,他說的“強弱類型”其實也是動靜類型的區(qū)分。

另外還有一個經(jīng)典的例子,C 語言之父 Dennis Ritchie 曾經(jīng)說 C  語言是一種“強類型但是弱檢查”的語言。如果對照成前文的定義,那他其實指的是“靜態(tài)類型弱類型”。

為什么這些大佬們會有混淆呢?

其實原因也很簡單,那就是在當(dāng)時還沒有明確的動靜類型與強弱類型的概念之分!或者說,那時候的強弱類型指的就是動靜類型。

維基百科上給出了 1970 年代對強類型的定義,基本可以還原成前文提到的靜態(tài)類型:

In 1974, Liskov and Zilles defined a strongly-typed language as one in which  "whenever an object is passed from a calling function to a called function, its  type must be compatible with the type declared in the called function."[3] In  1977, Jackson wrote, "In a strongly typed language each data area will have a  distinct type and each process will state its communication requirements in  terms of these types."[4]

前面幾位編程語言之父應(yīng)該就是持有類似的觀念。

不過,大佬們也意識到了當(dāng)時的“強弱類型”概念并不充分準(zhǔn)確,所以 Dennis Ritchie 才會說成“強類型但是弱檢查”,而且在訪談中,Guido  也特別強調(diào)了 Python 不應(yīng)該被稱為弱類型,而應(yīng)該說是運行時類型(runtime typing) 。

但是在那個早期年代,基本上強弱類型就等同于動靜類型,而這樣的想法至今仍在影響著很多人。

3、現(xiàn)在的強弱類型概念

早期對于編程語言的分類其實是混雜了動靜與強弱兩個維度,但是,它們并不是一一對應(yīng)重合的關(guān)系,并不足以表達編程語言間的區(qū)別,因此就需要有更為明確/豐富的定義。

有人提出了“type safety”、“memory safety”等區(qū)分維度,也出現(xiàn)了靜態(tài)檢查類型和動態(tài)檢查類型,與強弱類型存在一定的交集。

直到出現(xiàn) 2004 年的一篇集大成的學(xué)術(shù)論文《Type Systems》(出自微軟研究院,作者 Luca  Cardelli),專門研究編程語言的不同類型系統(tǒng):

Python是強類型語言還是弱類型語言

論文中對于強弱檢查(也即強弱類型)有一個簡短的歸納如下:

  • Strongly checked language: A language where no forbidden errors can occur at  run time (depending on the definition of forbidden error).

  • Weakly checked language: A language that is statically checked but provides  no clear guarantee of absence of execution errors.

其關(guān)鍵則是程序?qū)τ?untrapped errors 的檢查強度,在某些實際已出錯的地方,弱類型程序并不作捕獲處理,例如 C  語言的一些指針計算和轉(zhuǎn)換,而《C 程序員十誡》的前幾個都是弱類型導(dǎo)致的問題。

Python是強類型語言還是弱類型語言

論文對于這些概念的定義還是比較抽象的,由于未捕獲的錯誤(untrapped  errors)大多是由于隱式類型轉(zhuǎn)換所致,所以又演化出了第一節(jié)中的定義,以隱式類型轉(zhuǎn)換作為判斷標(biāo)準(zhǔn)。

如今將“對隱式類型轉(zhuǎn)換的容忍度”作為強弱類型的分類標(biāo)準(zhǔn),已經(jīng)是很多人的共識(雖然不夠全面,而且有一些不同的聲音)。

例如,維基百科就把隱式類型轉(zhuǎn)換作為弱類型的主要特點之一:

A weakly typed language has looser typing rules and may produce unpredictable  results or may perform implicit type conversion at runtime.

例如,以 Python 為例,社區(qū)的主流看法認(rèn)為它是強類型語言,而判斷的標(biāo)準(zhǔn)也是看隱式類型轉(zhuǎn)換。

例子有很多,比如 Python 官方的 wiki,它專門回答了Why is Python a dynamic language and also a  strongly typed language ,給出了 4 個答案,為 Python 的“動態(tài)強類型”定性:

Python是強類型語言還是弱類型語言

再比如,在《流暢的Python》第11章的雜談中,也專門提到了強弱類型的分類。(它的用語是“很少隱式類型轉(zhuǎn)換”,算是比較嚴(yán)謹(jǐn)?shù)?,但是也錯誤地把 C++  歸為了強類型。)

4、Python 是不是強類型語言?

關(guān)于“Python 是否屬于強類型”話題,在主流觀點之外,還存在著不少誤解的看法。

一方面的原因有些人混用了強弱類型與動靜類型,這有歷史的原因,前面已經(jīng)分析了。

另外還有一個同樣重要的原因,即有人把弱類型等同于“完全沒有隱式類型轉(zhuǎn)換”了,這種想法并不對。

事實上,強弱類型的概念中包含著部分相對主義的含義,強類型語言中也可能有隱式類型轉(zhuǎn)換。

比如,Rust 語言為了實現(xiàn)“內(nèi)存安全”的設(shè)計哲學(xué),設(shè)計了很強大的類型系統(tǒng),但是它里面也有隱式類型轉(zhuǎn)換(自動解引用)。

問題在于:怎么樣的隱式類型轉(zhuǎn)換是在合理范圍內(nèi)的?以及,某些表面的隱式類型轉(zhuǎn)換,是否真的是隱式類型轉(zhuǎn)換?

回到 Python 的例子,我們可以分析幾種典型的用法。

比如,"test"*3這種字符串“乘法”運算,雖然是兩種類型的操作,但是并不涉及隱式類型轉(zhuǎn)換轉(zhuǎn)化。

比如,x=10; x="test"先后給一個變量不同類型的賦值,表面上看 x 的類型變化了,用 type(x) 可以判斷出不同,但是,Python  中的類型是跟值綁定的(右值綁定),并不是跟變量綁定的。

變量 x 準(zhǔn)確地說只是變量名,是綁定到實際變量上的一個標(biāo)簽,它沒有類型。type(x) 判斷出的并不是 x 本身的類型,而是 x  指向的對象的類型,就像內(nèi)置函數(shù) id(x) 算出的也不是 x 本身的地址,而是實際的對象的地址。

比如,1 + True這種數(shù)字與布爾類型的加法運算,也沒有發(fā)生隱式類型轉(zhuǎn)換。因為 Python  中的布爾類型其實是整型的子類,是同一種類型!(如果有疑問,可查閱 PEP-285)

再比如,整數(shù)/布爾值與浮點數(shù)相加,在 Python 中也不需要作顯式類型轉(zhuǎn)換。但是,它的實現(xiàn)過程其實是用了數(shù)字的__add__()方法,Python  中一切皆對象,數(shù)字對象也有自己的方法。(其它語言可不一定)

也就是說,數(shù)字間的算術(shù)運算操作,其實是一個函數(shù)調(diào)用的過程,跟其它語言中的算術(shù)運算有著本質(zhì)的區(qū)別。

另外,不同的數(shù)字類型雖然在計算機存儲層面有很大差異,但在人類眼中,它們是同一種類型(寬泛地分),所以就算發(fā)生了隱式類型轉(zhuǎn)換,在邏輯上也是可以接受的。

最后,還有一個例子,即 Python 在 if/while 之后的真值判斷,我之前分析過它的實現(xiàn)原理,它會把其它類型的對象轉(zhuǎn)化成布爾類型的值。

但是,它實際上也只是函數(shù)調(diào)用的結(jié)果(__bool__() 和 __len__()),是通過計算而得出的合理結(jié)果,并不屬于隱式的強制類型轉(zhuǎn)換,不在  untrapped errors 的范疇里。

所以,嚴(yán)格來說,前面 5 個例子中都沒有發(fā)生類型轉(zhuǎn)換。 浮點數(shù)和真值判斷的例子,直觀上看是發(fā)生了類型轉(zhuǎn)換,但它們其實是 Python  的特性,是可控的、符合預(yù)期的、并沒有對原有類型造成破壞。

退一步講,若放寬“隱式類型轉(zhuǎn)換”的含義,認(rèn)為后兩個例子發(fā)生了隱式類型轉(zhuǎn)換,但是,它們是通過嚴(yán)謹(jǐn)?shù)暮瘮?shù)調(diào)用過程實現(xiàn)的,也不會出現(xiàn) forbidden  errors,所以還是屬于強檢查類型。

5、其它相關(guān)的問題前文對概念的含義以及 Python 中的表現(xiàn),作了細(xì)致的分析。接下來,為了邏輯與話題的完整性,我們還需要回答幾個小問題:

(1)能否以“隱式類型轉(zhuǎn)換”作為強弱類型的分類依據(jù)?

明確的分類定義應(yīng)該以《Type Systems》為準(zhǔn),它有一套針對不同 error 的分類,強弱類型其實是對于 forbidden errors  的處理分類。隱式類型轉(zhuǎn)換是其明顯的特征,但并不是全部,也不是唯一的判斷依據(jù)。

本文為了方便理解,使用這個主要特征來劃分強弱類型,但是要強調(diào),強類型不是沒有隱式類型轉(zhuǎn)換,而是可能有很少且合理的隱式類型轉(zhuǎn)換。

(2)假如有其它解釋器令 Python 支持廣泛的隱式類型轉(zhuǎn)換,那 Python 還是強類型語言么?

語言的標(biāo)準(zhǔn)規(guī)范就像是法律,而解釋器是執(zhí)法者。如果有錯誤的執(zhí)法解釋,那法律還是那個法律,應(yīng)該改掉錯誤的執(zhí)法行為;如果是法律本身有問題(造成了解釋歧義和矛盾,或者該廢棄),那就應(yīng)該修改法律,保證它的確定性(要么是強類型,要么是弱類型)。

(3)為什么說 Javascript 是弱類型?

因為它的隱式類型轉(zhuǎn)換非常多、非常復(fù)雜、非常過分!比如,Javascript 中123 + null結(jié)果為 123,123 +  {}結(jié)果為字符串“123[object Object]”。

另外,它的雙等號“==”除了有基本的比較操作,還可能發(fā)生多重的隱式類型轉(zhuǎn)換,例如true==['2']判斷出的結(jié)果為  false,而true==['1']的結(jié)果是 true,還有[]==![]和[undefined]==false的結(jié)果都為 true……

(4)C++ 是不是弱類型語言?

前文提到《流暢的Python》中將 C++ 歸為強類型,但實際上它應(yīng)該被歸為弱類型。C++ 的類型轉(zhuǎn)換是個非常復(fù)雜的話題,@櫻雨樓  小姐姐曾寫過一個系列文章做了系統(tǒng)論述,文章地址:如何攻克 C++ 中復(fù)雜的類型轉(zhuǎn)換?、詳解 C++ 的隱式類型轉(zhuǎn)換與函數(shù)重載!、誰說 C++  的強制類型轉(zhuǎn)換很難懂?

6、小結(jié)強弱類型概念在網(wǎng)上有比較多的爭議,不僅在 Python 是如此,在 C/C++ 之類的語言更甚。

其實在學(xué)術(shù)上,這個概念早已有明確的定義,而且事實上也被很多人所接納。

那些反對的聲音大多是因為概念混用,因為他們忽略了另一種對語言進行分類的維度;同時,還有一部分值得注意的原因,即不能認(rèn)為強類型等于“完全無隱式類型轉(zhuǎn)換”或“只要沒有xxx隱式類型轉(zhuǎn)換”。

到此,相信大家對“Python是強類型語言還是弱類型語言”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!


當(dāng)前名稱:Python是強類型語言還是弱類型語言
文章源于:http://weahome.cn/article/iisoep.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部