Python中的类型检查

本文中所有代码均运行在Python 2.7上

为什么要进行类型检查?

总所周知,Python是一门典型的动态语言,在变量定义、使用的过程中遵循duck typing,当对某一变量进行操作时才去检查它是否支持该操作。这在大多数情况下没有什么问题。但有时我们希望当面对非法类型的参数的时候采取某些默认处理机制,来提高程序的健壮性,而不是直接抛出异常停掉整个程序。
举个例子:

def list_add(list1, list2):
    for item in list2:
        list1.append(item)
    return list1

上面是一个很简单的方法,将第二个列表中的元素依此追加在第一个列表之后。这要求list1变量类型支持append方法,list2变量本身是可迭代的。如果我们传入两个int类型的变量来调用这个方法,就会抛出TypeError的异常。

type

在进行类型检查的时候,大多数人至少都会知道使用type方法,这是比较常见的方法。
再来几个例子:

>>> import typea
>>> type(1) is types.IntType
True
>>> type(True) is types.booleanType
True
>>> type(1.22) is types.StringType
False

看起来不错,似乎可以应付绝大多数情况,但有的时候还是会有点问题:

import types
# 我们创建了一个继承自int的类,不进行任何重写,按照duck typing的原则,它应该被按照int进行处理
>>> class A(int):
...       pass
>>> b = A()
>>> type(b) is types.IntType
False

可见,基于Python内建(bult-in)类型的自定义类型,python并不能返回我们期望的结果。
不仅如此,type对于古典类(古典类和新式类的区别)的类型判断似乎也有点问题:

>>> class A:
...        pass
>>> class B:
...        pass
>>> a = A()
>>> b = B()
>>> type(a) == type(b)
True
>>> type(a)
<type 'instance'>
>>> type(b)
<type 'instance'>

可见,对于所有古典类,type返回的结果是一样的。
综上所述,对于常见的内建类型,type可以返回我们期望的结果,但在某些情形下,似乎会有点问题。

isinstance

isinstance可以解决上面所提到的type可能存在的问题。
首先看一下常见情况下:

>>> isinstance(1, int)
True
>>> isinstance('Hello', basestring)
True
>>> isinstance(1.23, float)
True
>>> isinstance([1,2], dict)
False

接下来看看对于继承自内建类型的自定义类型的判断:

>>> class A(int):
...       pass
>>> a = A()
>>> isinstance(a, int)
True

之后来看看古典类的情况:

>>> class A:
...        pass
>>> class B:
...        pass
>>> a = A()
>>> b = B()
>>> isinstance(a, A)
True
>>> isinstance(a, B)
False
>>> isinstance(b, B)
True
>>> isinstance(b, A)
False

得到了我们所期望的效果。

总结

鉴于在某些情况下,type()可能会出现的问题,为确保程序的正常运行,一般情况下推荐使用isinstance()来进行类型判断。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 个人笔记,方便自己查阅使用 Py.LangSpec.Contents Refs Built-in Closure ...
    freenik阅读 67,925评论 0 5
  • http://python.jobbole.com/85231/ 关于专业技能写完项目接着写写一名3年工作经验的J...
    燕京博士阅读 7,755评论 1 118
  • 1、查询采购列表 purchase/findUserOrderPurchaseList 参数:在原接口上加上 or...
    西北狂刀阅读 452评论 0 0
  • 他与钱钟书并称为“南饶北钱”, 与季羡林并称为“南饶北季”。 他达古通今,学贯东西,在学问的天地里,硕果累累。 金...
    JaraPadma阅读 370评论 0 1
  • 蝶恋花 梦化蝴蝶多妩媚,萦绕轻歌,畅晚浑如醉。晏柳依依月姣美,群花俊赏藏暗翠。 年少幽闺从雨坠,空寄秋千,飘荡相思...
    易词斋主人阅读 857评论 33 49

友情链接更多精彩内容