type()和isinstance()之间有什么区别? [英] What are the differences between type() and isinstance()?

查看:167
本文介绍了type()和isinstance()之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这两个代码片段有什么区别?
使用 type()

What are the differences between these two code fragments? Using 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()


推荐答案

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

To summarize the contents of other (already good!) answers, isinstance caters for inheritance (an instance of a derived class is an instance of a base class, too), while checking for equality of type does not (it demands identity of types and rejects instances of subtypes, AKA subclasses).

通常,在Python中,你希望你的代码支持继承,当然(因为继承是如此方便,使用你的代码停止代码是不好的t!),所以 isinstance 比检查类型的标识要糟糕,因为它无缝地支持继承。

Normally, in Python, you want your code to support inheritance, of course (since inheritance is so handy, it would be bad to stop code using yours from using it!), so isinstance is less bad than checking identity of types because it seamlessly supports inheritance.

这不是 isinstance ,请注意 - 它只是不那么糟糕而不是检查类型的相等性。正常的,Pythonic,首选解决方案几乎总是鸭子打字:尝试使用参数,好像它是某种所需的类型,在尝试 / 除了语句捕获所有异常,如果参数实际上不是那种类型(或任何其他类型很好地模仿它;-),并且在除了子句之外,尝试别的东西(使用参数好像它是某种其他类型)。

It's not that isinstance is good, mind you—it's just less bad than checking equality of types. The normal, Pythonic, preferred solution is almost invariably "duck typing": try using the argument as if it was of a certain desired type, do it in a try/except statement catching all exceptions that could arise if the argument was not in fact of that type (or any other type nicely duck-mimicking it;-), and in the except clause, try something else (using the argument "as if" it was of some other type).

basestring ,但是,非常特殊的情况 - 内置类型让您使用 isinstance str unicode 子类即basestring )。字符串是序列(你可以循环它们,索引它们,切片它们......),但是你通常希望将它们视为标量类型 - 它有点不方便(但是一个相当频繁的用例)来处理各种类型的字符串(也许是其他标量类型,即你不能循环的那些)单向,所有容器(列表,集合,dicts,...)以另一种方式, basestring 加上 isinstance 帮助你做到这一点 - 这个成语的整体结构如下:

basestring is, however, quite a special case—a builtin type that exists only to let you use isinstance (both str and unicode subclass basestring). Strings are sequences (you could loop over them, index them, slice them, ...), but you generally want to treat them as "scalar" types—it's somewhat incovenient (but a reasonably frequent use case) to treat all kinds of strings (and maybe other scalar types, i.e., ones you can't loop on) one way, all containers (lists, sets, dicts, ...) in another way, and basestring plus isinstance helps you do that—the overall structure of this idiom is something like:

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

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

You could say that basestring is an Abstract Base Class ("ABC")—it offers no concrete functionality to subclasses, but rather exists as a "marker", mainly for use with isinstance. The concept is obviously a growing one in Python, since PEP 3119, which introduces a generalization of it, was accepted and has been implemented starting with Python 2.6 and 3.0.

PEP清楚地表明,虽然ABCs经常可以替代鸭子打字,但是这通常没有太大的压力(见这里)。然而,在最近的Python版本中实现的ABCs提供了额外的好处: isinstance (和 issubclass )现在不仅仅意味着[派生类的一个实例(特别是,任何类都可以与ABC注册,以便它将显示为子类,并将其实例显示为ABC的实例);和ABC也可以通过模板方法设计模式应用程序以非常自然的方式为实际的子类提供额外的便利(参见此处此处 [[部分II]]关于TM DP的更多信息,一般而言,特别是Python,独立于ABCs)。

The PEP makes it clear that, while ABCs can often substitute for duck typing, there is generally no big pressure to do that (see here). ABCs as implemented in recent Python versions do however offer extra goodies: isinstance (and issubclass) can now mean more than just "[an instance of] a derived class" (in particular, any class can be "registered" with an ABC so that it will show as a subclass, and its instances as instances of the ABC); and ABCs can also offer extra convenience to actual subclasses in a very natural way via Template Method design pattern applications (see here and here [[part II]] for more on the TM DP, in general and specifically in Python, independent of ABCs).

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

For the underlying mechanics of ABC support as offered in Python 2.6, see here; for their 3.1 version, very similar, see here. In both versions, standard library module collections (that's the 3.1 version—for the very similar 2.6 version, see here) offers several useful ABCs.

为了这个答案的目的,保留关于ABCs的关键(除了可以说更自然的TM DP功能放置,与mixin的经典Python替代方案相比)像 UserDict.DictMixin 这样的课程是他们制作的 isinstance (以及 issubclass )比过去更具吸引力和普及性(在Python 2.6和前进中)(在2.5及之前),因此,相比之下,在最近的Python版本中,使检查类型相等更糟糕它已经过去了。

For the purpose of this answer, the key thing to retain about ABCs (beyond an arguably more natural placement for TM DP functionality, compared to the classic Python alternative of mixin classes such as UserDict.DictMixin) is that they make isinstance (and issubclass) much more attractive and pervasive (in Python 2.6 and going forward) than they used to be (in 2.5 and before), and therefore, by contrast, make checking type equality an even worse practice in recent Python versions than it already used to be.

这篇关于type()和isinstance()之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆