天天看點

Python資料類型判斷常遇到的坑

python判斷變量資料類型時,建議使用isinstance()方法代替type(). 進行類型檢查首先想到的就是用type(),但是Type在某些特定情況下判斷類型存在問題,今天就來說下type在python類型判斷時的坑。

type()方法

例子: int類型判斷

>>> import types
>>> type(2017)==types.IntType
True
           

Python2.7中的types類型:

types.BooleanType              #  bool類型
types.BufferType               #  buffer類型
types.BuiltinFunctionType      #  内建函數,比如len()
types.BuiltinMethodType        #  内建方法,指的是類中的方法
types.ClassType                #  類類型
types.CodeType                 #  代碼塊類型
types.ComplexType              #  複數類型
types.DictProxyType            #  字典代理類型
types.DictType                 #  字典類型
types.DictionaryType           #  字典備用的類型
types.EllipsisType
types.FileType                 #  檔案類型
types.FloatType                #  浮點類型
types.FrameType
types.FunctionType             #  函數類型
types.GeneratorType       
types.GetSetDescriptorType
types.InstanceType             #  執行個體類型
types.IntType                  #  int類型
types.LambdaType               #  lambda類型
types.ListType                 #  清單類型
types.LongType                 #  long類型
types.MemberDescriptorType
types.MethodType               #  方法類型
types.ModuleType               #  module類型
types.NoneType                 #  None類型
types.NotImplementedType
types.ObjectType               #  object類型
types.SliceTypeh
types.StringType               #  字元串類型
types.StringTypes     
types.TracebackType   
types.TupleType                #  元組類型
types.TypeType                 #  類型本身
types.UnboundMethodType
types.UnicodeType    
types.XRangeType
           

Python3.x中的types類型:

types.BuiltinFunctionType
types.BuiltinMethodType
types.CodeType
types.DynamicClassAttribute
types.FrameType
types.FunctionType
types.GeneratorType
types.GetSetDescriptorType
types.LambdaType
types.MappingProxyType
types.MemberDescriptorType
types.MethodType
types.ModuleType
types.SimpleNamespace
types.TracebackType
types.new_class
types.prepare_class
           

Python3.x進行了類型的精簡

isinstance方法

isinstance(object, classinfo)
           

object表示執行個體,classinfo可以是直接或間接類名、基本類型或者有它們組成的元組。

基本用法

>>> isinstance(1, int)
True
>>> 
>>> isinstance('pythontab.com', (str, int)) # 是其中一種即可
True
>>> isinstance(100, (str, int)) # 是其中一種即可
True
           

上面type的例子可以表示為:

>>> import types
>>> isinstance(2017,int)
True
           

那為什麼不推薦使用type進行類型檢查呢?

我們來看一下下面的例子。

import types
class UserInt(int):
    def __init__(self, val=0):
        self.val = int(val)
i = 1
n = UserInt(2)
print(type(i) is type(n))
           

上面的代碼輸出:False

這就說明i和n的類型是不一樣的,而實際上UserInt是繼承自int的,是以這個判斷是存在問題的,當我們對Python内建類型進行擴充的時候,type傳回的結果就不夠準确了。我們再看一個例子。

class ca:
    pass
class cb:
    pass
a = ca()
b = cb()
print (type(a) is type(b))
           

代碼的輸出結果: True

注意: 這個例子僅僅針對Python2.x版本, Python3.x版本中會傳回Flase,不存在該問題

type比較的結果a和b的類型是一樣的,結果明顯是不準确的。在old-style class中,任意instance的type都是’instance’。是以絕對不能用type來判斷其類型。