为了账号安全,请及时绑定邮箱和手机立即绑定

Python中为什么推荐使用isinstance来进行类型判断?而不是type

标签:
Java Python

Python在定义变量的时候不用指明具体的的类型,解释器会在运行的时候会自动检查变量的类型,并根据需要进行隐式的类型转化。因为Python是动态语言,所以一般情况下是不推荐进行类型转化的。比如"+"操作时,如果加号两边是数据就进行加法操作,如果两边是字符串就进行字符串连接操作,如果两边是列表就进行合并操作,甚至可以进行复数的运算。解释器会在运行时根据两边的变量的类型调用不同的内部方法。当加号两边的变量类型不一样的时候,又不能进行类型转化,就会抛出TypeError的异常。

但是在实际的开发中,为了提高代码的健壮性,我们还是需要进行类型检查的。而进行类型检查首先想到的就是用type(),比如使用type判断一个int类型。

import typesif 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.BuiltinFunctionTypetypes.BuiltinMethodTypetypes.CodeTypetypes.DynamicClassAttributetypes.FrameTypetypes.FunctionTypetypes.GeneratorTypetypes.GetSetDescriptorTypetypes.LambdaTypetypes.MappingProxyTypetypes.MemberDescriptorTypetypes.MethodTypetypes.ModuleTypetypes.SimpleNamespacetypes.TracebackTypetypes.new_classtypes.prepare_class

但是我们并不推荐使用type来进行类型检查,之所以把这些类型列出来,也是为了扩展知识面。那为什么不推荐使用type进行类型检查呢?我们来看一下下面的例子。

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返回的结果就不够准确了。我们再看一个例子。

class A():
    passclass B():
    passa = 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



作者:xinxingzhao
链接:https://www.jianshu.com/p/7ef549503c93


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消