素材牛VIP会员
python判断变量类型时,为什么不推荐使用type()方法
 捂***功  分类:Python  人气:760  回帖:3  发布于6年前 收藏

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

>>> n = 911
>>> type(n)
<type 'int'>
>>> type(n) is int
True
 标签:python

讨论这个帖子(3)垃圾回帖将一律封号处理……

Lv3 码奴
gu***di 软件测试工程师 6年前#1

和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
Lv7 码师
ha***23 职业无 6年前#2

强烈推荐使用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...

Lv4 码徒
小***学 软件测试工程师 6年前#3

实际上还有一种方法是用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]

 文明上网,理性发言!   😉 阿里云幸运券,戳我领取