Python数据类型判断常遇到的坑

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来判断其类型。


另外这个问题又与Python的思想有关,正常情况下不应该编写代码检查类型的,而应该直接假设被操作的instance具有你希望的属性,否则抛出异常。即使需要检查类型,也应该用isinstance来判断,这样你期望类型的subclass也能正常被处理(比如,一个函数需要处理Message类型,那么它应该也能处理Message的子类型MyMessage,所以应该使用isinstance(arg,Message)这样来判断而不是type(arg) == Message来判断)



结论:


尽量不要使用type()方法,多使用isinstance(),这样可以减少错误。


以上是 Python数据类型判断常遇到的坑 的全部内容, 来源链接: utcz.com/z/523410.html

回到顶部