Python中為什么推薦使用isinstance來進行類型判斷?而不是type


轉自:http://www.xinxingzhao.com/blog/2016/05/23/python-type-vs-isinstance.html

Python在定義變量的時候不用指明具體的的類型,解釋器會在運行的時候會自動檢查 變量的類型,並根據需要進行隱式的類型轉化。因為Python是動態語言,所以一般情 況下是不推薦進行類型轉化的。比如"+"操作時,如果加號兩邊是數據就進行加法操 作,如果兩邊是字符串就進行字符串連接操作,如果兩邊是列表就進行合並操作,甚 至可以進行復數的運算。解釋器會在運行時根據兩邊的變量的類型調用不同的內部方法。 當加號兩邊的變量類型不一樣的時候,又不能進行類型轉化,就會拋出TypeError的異常。

但是在實際的開發中,為了提高代碼的健壯性,我們還是需要進行類型檢查的。而進行 類型檢查首先想到的就是用type(),比如使用type判斷一個int類型。

import types if type(1) is types.Integer: print('1是int類型') else: print('1不是int類型') 

上面的程序會輸出:1是int類型

我們在types中可以找到一些常用的類型,在2.7.6中顯示的結果:

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 

在Python 3中,類型已經明顯減少了很多

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

但是我們並不推薦使用type來進行類型檢查,之所以把這些類型列出來,也是為了擴展知識 面。那為什么不推薦使用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 A(): pass class B(): pass a = A() b = B() print(type(a) is type(b)) 

代碼的輸出結果: True

type比較的結果a和b的類型是一樣的,結果明顯是不准確的。這種古典類的實例,type返回的結果都 是一樣的,而這樣的結果不是我們想要的。對於內建的基本類型來說,使用tpye來檢查是沒有問題的, 可是當應用到其他場合的時候,type就顯得不可靠了。這個時候我們就需要使用isinstance來進行類型 檢查。

isinstance(object, classinfo)

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

>>> isinstance(2, float)
False
>>> isinstance('a', (str, unicode))
True
>>> isinstance((2, 3), (str, list, tuple))
True


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM