首页 > Python > type() 和 isinstance() 有什么区别?

type() 和 isinstance() 有什么区别?

上一篇 下一篇

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

用:type

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()

分割线

网友回答:

下面是一个无法实现的目标的示例:isinstancetype

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.

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

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

分割线

网友回答:

总结其他(已经很好!)答案的内容,迎合继承(派生类的实例也是基类的实例),同时检查不相等(它要求类型的标识并拒绝子类型的实例,AKA 子类)。isinstancetype

通常,在 Python 中,你当然希望你的代码支持继承(因为继承非常方便,所以阻止使用你的代码使用它会很糟糕!),所以比检查 s 的身份要少,因为它无缝地支持继承。isinstancetype

请注意,这并不是一件好事——它只是比检查类型的相等性要好。正常的,Pythonic的,首选的解决方案几乎总是“鸭子类型”:尝试使用参数,就好像它是某种所需的类型一样,在/语句中执行此操作,捕获如果参数实际上不是该类型(或任何其他类型很好地模仿它;-)可能出现的所有异常,并在子句中尝试其他东西(使用参数“好像”它是其他类型的)。isinstancetryexceptexcept

basestring 但是,这是一个非常特殊的情况 – 一个内置类型,它的存在只是为了让你使用(两者和子类)。字符串是序列(你可以循环它们,索引它们,切片它们,…),但你通常希望将它们视为“标量”类型——以一种方式处理所有类型的字符串(也许还有其他标量类型,即你不能循环的字符串),所有容器(列表,集合,字典等)以一种方式处理,这有点不合时宜(但这是一个相当频繁的用例), Plus 可以帮助您做到这一点 – 这个成语的整体结构是这样的:isinstancestrunicodebasestringbasestringisinstance

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

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

PEP明确表示,虽然ABC通常可以替代鸭子类型,但通常没有很大的压力(见这里)。然而,在最近的Python版本中实现的ABC确实提供了额外的好处:(和)现在不仅仅意味着“派生类的[实例]”(特别是,任何类都可以向ABC“注册”,以便它显示为子类,其实例显示为ABC的实例);ABC还可以通过模板方法设计模式应用程序以非常自然的方式为实际的子类提供额外的便利(有关TM DP的更多信息,请参阅此处和此处[[Part II]],一般而言,特别是在Python中,独立于ABC)。isinstanceissubclass

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

出于这个答案的目的,关于ABC的关键(除了TM DP功能的更自然的位置,与UserDict.DictMixin等混合类的经典Python替代品相比)是它们使(和)比以前(在Python 2.6及以后)更具吸引力和普遍性(在Python 2.5及以后)。 因此,相比之下,在最近的 Python 版本中,检查类型相等性的做法比以前更糟糕。isinstanceissubclass

分割线

网友回答:

Python 和 中的区别?isinstance()type()

类型检查

isinstance(obj, Base)

允许子类的实例和多个可能的基:

isinstance(obj, (Base1, Base2))

而类型检查

type(obj) is Base

仅支持引用的类型。


作为旁注,可能比is

type(obj) == Base

因为类是单例。

避免类型检查 – 使用多态性(鸭子类型)

在 Python 中,通常您希望允许参数使用任何类型的参数,将其视为预期,如果对象的行为不符合预期,它将引发适当的错误。这称为多态性,也称为鸭子类型。

def function_of_duck(duck):
    duck.quack()
    duck.swim()

如果上面的代码有效,我们可以假设我们的参数是一只鸭子。因此,我们可以传入其他东西是鸭子的实际子类型:

function_of_duck(mallard)

或者像鸭子一样工作:

function_of_duck(object_that_quacks_and_swims_like_a_duck)

我们的代码仍然有效。

但是,在某些情况下,需要显式类型检查。
也许您对不同的对象类型有明智的处理。例如,可以从字典记录构造 Pandas 数据帧对象。在这种情况下,您的代码需要知道它正在获取哪种类型的参数,以便它可以正确处理它。

所以,要回答这个问题:

Python 和 中的区别?isinstance()type()

请允许我演示一下区别:

type

假设如果你的函数获得某种类型的参数(构造函数的常见用例),你需要确保某种行为。如果检查如下类型:

def foo(data):
    '''accepts a dict to construct something, string support in future'''
    if type(data) is not dict:
        # we're only going to test for dicts for now
        raise ValueError('only dicts are supported for now')

如果我们尝试传入一个子类的字典(我们应该能够,如果我们希望我们的代码遵循 Liskov 替换的原则,那么子类型可以替换为类型)我们的代码就会中断!dict

from collections import OrderedDict

foo(OrderedDict([('foo', 'bar'), ('fizz', 'buzz')]))

引发错误!

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in foo
ValueError: argument must be a dict

isinstance

But if we use , we can support Liskov Substitution!:isinstance

def foo(a_dict):
    if not isinstance(a_dict, dict):
        raise ValueError('argument must be a dict')
    return a_dict

foo(OrderedDict([('foo', 'bar'), ('fizz', 'buzz')]))

返回OrderedDict([('foo', 'bar'), ('fizz', 'buzz')])

抽象基类

事实上,我们可以做得更好。 提供抽象基类,这些基类对各种类型的强制实施最小协议。在我们的例子中,如果我们只期望协议,我们可以执行以下操作,我们的代码变得更加灵活:collectionsMapping

from collections import Mapping

def foo(a_dict):
    if not isinstance(a_dict, Mapping):
        raise ValueError('argument must be a dict')
    return a_dict

对评论的回应:

应该注意的是,类型可用于检查多个类type(obj) in (A, B, C)

是的,您可以测试类型的相等性,但不要使用上述方法,而是使用控制流的多个基库,除非您明确只允许这些类型:

isinstance(obj, (A, B, C))

同样,区别在于支持可以替换父类而不会破坏程序的子类,这种属性称为 Liskov 替换。isinstance

但是,更好的是,反转依赖项,根本不检查特定类型。

结论

因此,由于我们希望支持替换子类,因此在大多数情况下,我们希望避免使用类型检查,而更喜欢使用类型检查 – 除非您确实需要知道实例的精确类。typeisinstance

模板简介:该模板名称为【type() 和 isinstance() 有什么区别?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【Python】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 237次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 03-06
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
单页式简历模板 微信模板 微信素材 微信公众平台 企业网站 html5 微信文章 自适应 响应式 微信图片
您可能会喜欢的其他模板