这两个代码片段之间有什么区别?

使用类型:

import types

if type(a) is types.DictType:
    do_something()
if type(b) in types.StringTypes:
    do_something_else()

使用isinstance:

if isinstance(a, dict):
    do_something()
if isinstance(b, str) or isinstance(b, unicode):
    do_something_else()

当前回答

根据python文档,这里有一条声明:

8.15.types-内置类型的名称从Python 2.2开始,内置工厂函数,如int()和str()也是相应的类型。

因此,isinstance()应该优先于type()。

其他回答

根据python文档,这里有一条声明:

8.15.types-内置类型的名称从Python 2.2开始,内置工厂函数,如int()和str()也是相应的类型。

因此,isinstance()应该优先于type()。

为了总结其他(已经很好了!)答案的内容,isinstance迎合了继承(派生类的实例也是基类的实例),而检查类型的相等性则没有(它要求类型的身份,拒绝子类型(AKA子类)的实例)。

通常,在Python中,您希望您的代码支持继承(因为继承非常方便,所以阻止使用您的代码使用它是不好的!),所以与检查类型标识相比,isinstance没有那么糟糕,因为它无缝地支持继承。

这并不是说这是好的,但请注意,这比检查类型的相等性差得多。正常的、Python式的、首选的解决方案几乎都是“duck-type”:尝试将参数用作某个所需的类型,在try/except语句中执行,捕获如果参数实际上不是该类型(或任何其他类型很好地模仿它;-)可能出现的所有异常,在except子句中,尝试其他方法(使用参数“好像”它是其他类型的)。

然而,basestring是一种非常特殊的内置类型,它只允许您使用isinstance(str和unicode子类basestring)。字符串是序列(你可以对它们进行循环、索引、切片……),但你通常希望将它们视为“标量”类型——以一种方式处理所有类型的字符串(可能还有其他标量类型,即你不能循环的字符串),以另一种方式对待所有容器(列表、集合、字典……)有点不方便(但这是一个相当频繁的用例),而basestring加isinstance有助于实现这个习惯用法的整体结构如下:

if isinstance(x, basestring)
  return treatasscalar(x)
try:
  return treatasiter(iter(x))
except TypeError:
  return treatasscalar(x)

你可以说basestring是一个抽象基类(“ABC”)——它没有为子类提供具体的功能,而是作为一个“标记”存在,主要用于isinstance。这个概念在Python中显然是一个不断增长的概念,因为引入了它的泛化的PEP 3119被接受,并从Python 2.6和3.0开始实现。

政治公众人物明确表示,虽然ABC通常可以代替鸭子打字,但一般来说,这样做没有太大的压力(见这里)。然而,在最近的Python版本中实现的ABC确实提供了额外的好处:isinstance(和issubclass)现在不仅仅意味着“派生类的实例”(特别是,任何类都可以向ABC“注册”,这样它将显示为子类,其实例将显示为ABC的实例);而ABC也可以通过模板方法设计模式应用程序以非常自然的方式为实际的子类提供额外的便利(参见此处和此处的[[第二部分]],了解有关TM DP的更多信息,通常是在Python中,独立于ABC)。

有关Python 2.6中提供的ABC支持的基本机制,请参阅此处;对于他们的3.1版本,非常相似,请参见此处。在这两个版本中,标准库模块集合(这是3.1版本,与2.6版本非常相似,请参见此处)提供了几个有用的ABC。

为了回答这个问题,要保留ABC的关键之处(除了与UserDict.DictMixin之类的混合类的经典Python替代品相比,TM DP功能的放置更自然之外)是,它们使isinstance(和issubclass)比过去(在Python 2.6和之前)更具吸引力和普遍性,因此,相比之下,在最近的Python版本中,检查类型相等比以前更糟糕。

实际用法的不同之处在于它们如何处理布尔值:

True和False只是python中表示1和0的关键字。因此

isinstance(True, int)

and

isinstance(False, int)

两者都返回True。两个布尔值都是整数的实例。然而,type()更聪明:

type(True) == int

返回False。

下面是一个例子,isinstance实现了类型无法实现的功能:

class Vehicle:
    pass

class Truck(Vehicle):
    pass

在本例中,卡车对象是车辆,但您将看到:

isinstance(Vehicle(), Vehicle)  # returns True
type(Vehicle()) == Vehicle      # returns True
isinstance(Truck(), Vehicle)    # returns True
type(Truck()) == Vehicle        # returns False, and this probably won't be what you want.

换句话说,对于子类也是如此。

另请参阅:如何比较Python中对象的类型?

type()和isinstance()之间的区别

type()->返回对象的类型

isinstance()->返回布尔值

一般来说,isinstance是一种“更”优雅的检查对象是否属于某种“类型”的方法(因为您知道继承链)。

另一方面,如果您不知道继承链,需要进行pick,请选择类型(x)==。。。

类型的另一个有趣的例子是检查bool

----Case bool----

print(type(True) == int) # False
print(type(False) == int) # False
print(type(True) == bool) # True
print(type(False) == bool) # True

print(isinstance(True, int)) # True
print(isinstance(True, int)) # True



----Case inheritance----
class A:
    x=1

class B(A):
    x=2

class C(B):
    x=3
    
var1 = A()
var2 = B()
var3 = C()

print(type(var1)) # <class '__main__.A'>
print(type(var1) == A) # True
print(type(var2) == A) # False
print(type(var3) == A) # False

print(isinstance(var1, A)) # True
print(isinstance(var2, A)) # True
print(isinstance(var3, A)) # True



print(type(var2)) # <class '__main__.B'>
print(type(var1) == B) # False
print(type(var2) == B) # True
print(type(var3) == B) # False

print(isinstance(var1, B)) # False
print(isinstance(var2, B)) # True
print(isinstance(var3, B)) # True



print(type(var3)) # <class '__main__.C'>
print(type(var1) == C) # False
print(type(var2) == C) # False
print(type(var3) == C) # True

print(isinstance(var1, C)) # False
print(isinstance(var2, C)) # False
print(isinstance(var3, C)) # True