Python是不是弱類型?如果是的話是不是僅僅因此就不需要泛型了?


請先理解以下基本概念:

  1. python是強類型;

  2. 泛型是啥。


「不需要泛型」和強/弱類型無關,另外一般認為Python是強類型

泛型屬於多態的概念。廣義的多態包括:Ad-hoc多態(函數重載),參數化多態(泛型),子類型多態。

泛型是指:函數的類型簽名中可以包含類型變數,使用時類型變數會被靜態地替換成具體類型,而針對不同具體類型的函數體是一模一樣的。

如C++的template,T是類型變數

T max(T x, T y)
{
return x &< y ? y : x; }

Haskell,a是類型變數。

replicate 0 _ = []
replicate n a = a : replicate (n - 1) a

Java把類型變數擦除成object算不算呢。。算不算呢。。(洗個「地」,之所以這樣做,蠢是一方面,和Java語法、JDK類庫的歷史包袱也有關)

靜態類型語言利用多態(包括泛型)機制,可以實現動態類型的便利,同時又避免了動態類型的性能、安全問題。(靜態確定變數/函數的類型對於data representations, alignment,和register selection等都十分重要)

可以認為泛型是靜態語言的概念。或者也可以這麼說:動態語言「天生」就支持泛型,只不過代價大了點。。


  • Python 是強類型的

  • Python 不需要泛型是因為 Python 的變數簽名是動態的,有 lazy binding 效果。比如一個函數傳入 connection 參數,然後函數中調用 connection.close() 。直到你調用這個函數的時候(運行期),虛擬機才會去查找 close 方法,而不是像靜態類型語言一樣在編譯期或裝載期就事先建立符號表。


Duck Typing, C++ 式的編譯期泛型和 Java Collection Framework 1.4 之前的基於介面的做法,目的相似,手段不同而已。

http://en.wikipedia.org/wiki/Duck_typing


一句話:泛型是一種類型聲明的表達方法。Python不聲明類型,所以你想找泛型也沒處找去。跟強/弱類型和靜態/動態都沒有直接聯繫。

一般的解釋語言為了編程的靈活性,都沒有類型聲明。這是被變數都要聲明類型的語言坑慘的程序汪的報復。比如說Java,一屏幕代碼,四分之一都是沒啥信息量的局部變數類型聲明,光看都要瞎了有沒有。

但是類型聲明還是有好處的啊,寫Python的程序員肯定遇到過處理exception(比如連不上伺服器)的代碼里類型錯誤,結果程序寫的時候好好的,跑的時間一長就類型錯誤,簡直吐血三升有木有。有類型聲明的話,寫的時候就能發現錯誤了。

所以呢,解釋語言的程序汪們就又往語言里加可選的類型聲明了。比如Python有mypy,既有泛型又有duck-typing,簡直左牽黃右擎蒼啊。以後再也不要說我們解釋語言不做類型檢查了,是我們不愛做而已。

mypy - Optional Static Typing for Python


先來看看為啥Java需要Generics?

官網有解答:http://docs.oracle.com/javase/tutorial/java/generics/why.html

總的來說,Generics根據這個解釋,主要作用就是在編譯期做類型檢查+避免不必要的類型轉換。

Python(2.x)的確切的類型信息本身要等到運行時才會暴露出來,自然編譯期做類型檢查也就沒有意義了。


因為Python是動態類型,所以天然就是支持泛型支持泛型的。但是動態類型語言,都自然支持泛型


python/ruby 都是強類型的……php是弱的


看了一些回答後,再次感嘆python的確又是一個類似C++那般被國外再到國內被誤解相當深的編程語言工具。

1. 為變數指定數據類型稱為「強類型」,但此形式並不代表該編程語言類型系統一定更強大。Python有一個統一的、明確的、強大的類型系統,比Java的類型系統更強。

2. 見你這樣問,顯然對「泛型」的理解只是形式上的,建議你還是認真看看其定義和目的、意義:http://zh.wikipedia.org/zh-cn/%E6%B3%9B%E5%9E%8B


推薦閱讀:

windows下anaconda 安裝報錯, errno9,怎麼解決?
spyder 如何添加和安裝其他的包?
Python 做高頻交易系統適合哪個級別的延遲?
為什麼 Python 中列表的 sort 方法一定要返回 None 而不是排序後的列表?
已有C++基礎,python入門書籍推薦?

TAG:程序員 | 編程語言 | Python | 編程 |