天天看點

Python 的動态類型系統

Python 與 ABC 的一個重要差別在于其類型系統。

ABC 采用靜态類型,編譯器會檢查程式中的變量類型是否保持一緻,如果不一緻,程式就無法運作。并且,ABC與當時大多數靜态語言不同,采用的是 類型推導 (和 Haskell 一樣),而不是類型聲明 (比如 C 語言)。而 Python 采用動态類型,所有類型檢查都是在程式運作過程中,而不是編譯時進行的。

不過,Python 的類型系統與 ABC 也沒有大家所想的那麼大的差別。

與其它靜态語言不同,ABC 除了在編譯時進行類型檢查,在運作時還會再次檢查。在ABC的原型中,并沒有實作完整的編譯時類型檢查,于是,運作時類型檢查可以作為一種驗證方式。同時,運作時類型檢查可以抛出清楚的異常資訊,對debug也很有幫助,否則,語言核心可能會因為一些類型錯誤直接崩潰。

ABC 采用運作時類型檢查的最主要的原因,在于它是一種互動式語言。

在互動式場景中,使用者輸入的每一句代碼,都是立即執行的,是以,完全有可能建立一個數字變量,删除它,又建立一個同名的字元串變量。如果這樣的指派過程出現在同一段代碼中,顯然是無法編譯通過的,但在互動式場景中,禁止這種操作也不合理。作為妥協,ABC 對全局變量采用動态類型檢查,而局部變量采用靜态類型檢查——為了簡化實作,幹脆所有變量都在運作時再次檢查。

是以,實際上 Python 的類型檢查系統實作得很簡單——隻是完全抛開 ABC 的編譯時類型檢查而已。這很符合 Python 的“抄近道”哲學,因為所有的類型錯誤都在執行前檢查過了,是以這個簡單的實作完全不影響程式的可靠性。

不過,一旦采用動态類型系統,就和靜态類型徹底告别了。

在 ABC 中,精心設計的内置操作可以根據輸入内容的具體形式來推斷其類型(譯注:ABC采用類型推導而不是類型聲明),比如說,根據“x^y”,編譯器可以推斷,x 和 y 都是字元串,這個操作的結果也一定是字元串。而在 Python 中則沒法做這樣的推斷,比如“x + y”有可能是字元串拼接,也可能是數字相加,也可能是使用者自定義類型重載加号之後的某種操作。