咱們都知道, python是一個強類型的語言, 也是一個動態類型的語言. 可是在python2.X系列中, 這個強類型是須要打折扣的, 是很是接近強類型.html
咱們來看下面的代碼片斷python
In [1]: 'a' < 1000 Out[1]: False
字符串和整型竟然能夠比較, 這個是個很是奇怪的行爲. 強類型的語言是不該該容許有這種類型間的隱式轉換的, 因此這種比較應該是報錯的纔對. Java就是這樣的一個語言. 不過強類型的語言中, 是能夠各類數字類型之間存在隱式轉換的.編程
python的這個字符串和整形的比較是很是特別的, python中是沒有字符類型(char)的, 單引號和雙引號都是字符串類型. 測試
這字符串和整型的比較是按照ASCII表的順序麼? 顯然也不是. 'a'對應的ascii碼是97, 'a' < 1000就是97 < 1000, 應該返回True纔對.spa
官網文檔(參考3)對這個東西做出這樣的解釋:htm
CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don’t support proper comparison are ordered by their address.對象
CPython的實現細節彙總: blog
規則1: 除數字類型外不一樣類型的對象是按照類型的名字來排序的.排序
規則2: 不支持比較操做的相同類型的對象是按照地址來排序的.ci
[我查到stackoverflow(參考2)也有人對這個東西做出補充.]
規則3: 比較兩個字符串或兩個數字類型, 比較結果是符合預期的(字符串是字典順序, 整型是數字大小的順序)
原文: When you order two strings or two numeric types the ordering is done in the expected way (lexicographic ordering for string, numeric ordering for integers).
規則4:比較數字類型和非數字類型的時候, 數字類型在前(就是數字類型 < 非數字類型)
原文: When you order a numeric and a non-numeric type, the numeric type comes first.
規則1的例外: 舊風格的類小於新風格的類.
原文: One exception is old-style classes that always come before new-style classes.
咱們能夠發現, 其實CPython的強類型不是真的, 存在不少陷進.
下面我對這幾個查到的規則進行驗證
class Foo(object): pass class Bar(object): pass # 規則1 print Foo() > Bar() # 規則2 a, b = Foo(), Foo() print id(a) > id(b), id(a), id(b) print a > b # 規則3 print 100 > 1 print 'b' > 'a' class Foo: pass class Bar(object): pass # 規則4 print Foo > 1000 # classobj > int f = Foo() print id(f) < id(1000), id(f), id(1000), id(1000) print f < 1000 # old-style class instance > int 應該是 Foo() > 1000, 這不符合規則4, Foo是old-style類 print Bar() > 1000 # new-style class instance > int print 'a' > 1000 # str > int print {} > 1000 # dict > int print [] > 1000 # list > int print (1,) > 1000 # tuple > int # 規則1的例外 print Foo() < Bar() # old-style class < new-style class
上面代碼的全部比較表達式都是True. 測試環境是2.7.6
我發現這些規則也出現了例外, Foo() > 1000, Foo是old-style類, 是這個緣由麼? 不理解, 反正這是個很是困惑的實現方式.
若是有知道的朋友, 麻煩留言告知一下, 這個實現真的是很是困惑. 咱們平常使用的過程當中, 要很是注意判斷類型以後再比較, 防止這類陷進.
幸運的是python 3.X已經修正了這個問題, 參考2的例子
>>> '10' > 5 Traceback (most recent call last): File "", line 1, in '10' > 5 TypeError: unorderable types: str() > int()
CPython獲取對象地址的方法是id(), 官網給出了這樣的解釋: This is the address of the object in memory.
水平有限, 歡迎拍磚!
參考資料: