python判斷變量類型時,判斷一個變量的類型時爲何不使用type(),而是用isinstance()方法

注意:本文代碼測試均在python2.75環境html

python判斷變量數據類型目前有兩種方法:python

第一種方法使用type()方法:segmentfault

In [22]: type(111)==int
Out[22]: False

In [25]: import types

In [26]: type(111)==types.IntType
Out[26]: True

第二種方法使用isinstance()方法:python2.7

In [27]: isinstance(111,int)
Out[27]: True

不使用type()代碼示例:函數

代碼示例:post

class A(object): 
    pass
  
class B(A): 
    pass
  
print type(A()) == A         # True
print type(B()) == A         # False
print isinstance(A(),A)      # True
print isinstance(B(),A)      # True

特殊代碼示例:測試

from collections import Iterator
class A(object):
    def __iter__(self):
     pass
    def next(self):
     pass

isinstance(A(), Iterator)        # True
type(A()) == Iterator            # False

一個明顯的區別是在判斷子類。這個主要是因爲python新式類和舊式類區別形成,相關連接:http://www.python.org/doc/new...code

type()不會認爲子類是一種父類類型。htm

isinstance()會認爲子類是一種父類類型繼承

正常狀況下不該該編寫代碼檢查類型的,而應該直接假設被操做的instance具備你但願的屬性,不然拋出異常。即便須要檢查類型,也應該用isinstance來判斷,這樣你指望類型的subclass也能正常被處理(好比,一個函數須要處理Message類型,那麼它應該也能處理Message的子類型MyMessage,因此應該使用isinstance(arg,Message)這樣來判斷而不是type(arg) == Message來判斷)。

參考Duck Typing http://en.wikipedia.org/wiki/...

代碼示例額2:

import typesclass UserInt(int):
    def __init__(self, val=0):
        self.val = int(val)

i = 1n = UserInt(2)
print(type(i) is type(n))    # False

這就說明i和n的類型是不同的,而實際上UserInt是繼承自int的,因此這個判斷是存在問題的,當咱們對Python內建類型進行擴展的時候,type返回的結果就不夠準確了。這就說明i和n的類型是不同的,而實際上UserInt是繼承自int的,因此這個判斷是存在問題的,當咱們對Python內建類型進行擴展的時候,type返回的結果就不夠準確了。

代碼示例3:

class A():
    pass
    
class B():
    pass
    
a = A()
b = B()

print(type(a) is type(b))    # True

type比較的結果a和b的類型是同樣的,結果明顯是不許確的。這種古典類的實例,type返回的結果都是同樣的,而這樣的結果不是咱們想要的。對於內建的基本類型來講,使用tpye來檢查是沒有問題的,但是當應用到其餘場合的時候,type就顯得不可靠了。

結論:

儘可能不要使用type()方法,多使用isinstance(),這樣能夠減小錯誤。

參考:

http://www.chenxm.cc/post/429...

相關文章
相關標籤/搜索