python判断变量类型时,为什么不推荐使用type()方法

用type()这种判断变量的方法,结果老鸟被鄙视了,不知所以然。
求各位讲解:这个问题出在哪里,怎样判断一个变量的类型才是好方法?

>>> n = 911
>>> type(n)
<type 'int'>
>>> type(n) is int
True
阅读 184.7k
评论 2012-10-12 提问
    4 个回答

    实际上还有一种方法是用isinstance
    比如:

    a = 111
    isinstance(a, int)
    True

    isinstance 和 type的区别在于:

    class A:
        pass
    
    class B(A):
        pass
    
    isinstance(A(), A)  # returns True
    type(A()) == A      # returns True
    isinstance(B(), A)    # returns True
    type(B()) == A        # returns False

    区别就是 对于subclass之类的 type就不行事了

    你说的老鸟 应该是这个意思吧? [颤抖ing]

      • 2.6k

      和Python的new-style class有关。相关链接 http://www.python.org/doc/newstyle/

      以下代码在Python2.5中执行:

      >>> class A:
      ...  pass
      ... 
      >>> a = A()
      >>> class B:
      ...  pass
      ... 
      >>> b = B()
      >>> type(a) is type(b)
      True
      >>>

      在old-style class中,任意instance的type都是'instance'。所以绝对不能用type来判断其类型。

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

      另外这个问题还与metaclass有关,但是我实在想不起来在哪个地方会导致type()返回的不是type这个class的instance了…待补充…

      UPDATE:
      又找到这段例子,供参考

      Python 2.7.3 (default, May 12 2012, 00:10:31) 
      [GCC 4.2.1 (Gentoo 4.2.1_p5666, Apple Inc. build 5666) (dot 3)] on darwin
      Type "help", "copyright", "credits" or "license" for more information.
      >>> from collections import Iterator
      >>> class A(object):
      ...  def __iter__(self):
      ...   pass
      ...  def next(self):
      ...   pass
      ... 
      >>> isinstance(A(), Iterator)
      True
        • 1
        • 新人请关照

        1、type可以只接收一个参数,打印其未知的所属的类型;而isinstance只能判断是否属于某个已知类型,所以,isinstance效率更高一些

        2、isinstance可以判断子类对象是否继承于父类;而type不可以,type只能把类对象识别为instance实例类型,即老式类都是通过instance创建的

        所以,type主要用于获取未知变量的类型,isinstance主要用于判断A类是否继承于B类

          强烈推荐使用isinstance()方法代替type(),以下两个示例讲解为什么不使用type(),如果看完觉得还不满意可以去http://www.chenxm.cc/post/429...

          代码示例额2:
          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返回的结果就不够准确了。这就说明i和n的类型是不一样的,而实际上UserInt是继承自int的,所以这个判断是存在问题的,当我们对Python内建类型进行扩展的时候,type返回的结果就不够准确了。

          代码示例3:

          class A():
              pass
              
          class B():
              pass
              
          a = A()
          b = B()
          
          print(type(a) is type(b))    # True
          

          type比较的结果a和b的类型是一样的,结果明显是不准确的。这种古典类的实例,type返回的结果都是一样的,而这样的结果不是我们想要的。对于内建的基本类型来说,使用tpye来检查是没有问题的,可是当应用到其他场合的时候,type就显得不可靠了。

          http://www.chenxm.cc/post/429...

            撰写回答

            登录后参与交流、获取后续更新提醒