Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
346 views
in Technique[技术] by (71.8m points)

python - type()和isinstance()之间有什么区别?(What are the differences between type() and isinstance()?)

What are the differences between these two code fragments?

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

Using type() :

(使用type() :)

import types

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

Using isinstance() :

(使用isinstance() :)

if isinstance(a, dict):
    do_something()
if isinstance(b, str) or isinstance(b, unicode):
    do_something_else()
  ask by abbot translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

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

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 type s because it seamlessly supports inheritance.

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

It's not that isinstance is good , mind you—it's just less bad than checking equality of types.

(并不是因为isinstance好的 ,请注意 - 它比检查类型的相等性更糟糕 。)

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

(正常的,Pythonic,首选解决方案几乎总是“鸭子打字”:尝试使用该参数,就好像它是某种期望的类型一样,在try / except语句中执行它,捕获可能出现的所有异常,如果参数实际上不是那种类型(或任何其他类型很好地模仿它;-),并在except子句中,尝试其他东西(使用参数“好像”它是其他类型)。)

basestring is , however, quite a special case—a builtin type that exists only to let you use isinstance (both str and unicode subclass basestring ).

(但是, basestring 一个非常特殊的情况 - 内置类型存在让你使用isinstancestrunicode子类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, ie, 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:

(字符串是序列(你可以循环它们,索引它们,切片它们......),但你通常希望将它们视为“标量”类型 - 它有点不方便(但是一个相当频繁的用例)来处理各种类型的字符串(也许是其他标量类型,即你无法循环的那些)单向,所有容器(列表,集合,dicts,......)以另一种方式, basestring plus isinstance帮助你做到这一点 - 整体结构这个成语是这样的:)

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

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 .

(你可以说basestring是一个抽象基类 (“ABC”) - 它没有为子类提供具体的功能,而是作为“标记”存在,主要用于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.

(这个概念在Python中显然是一个不断增长的概念,因为引入它的概括的PEP 3119被接受并且已经从Python 2.6和3.0开始实现。)

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

(PEP清楚地表明,虽然ABCs经常可以替代鸭子打字,但通常没有很大的压力(见这里 )。)

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

(然而,在最近的Python版本中实现的ABCs提供了额外的好处: isinstance (和issubclass )现在不仅仅意味着“[派生类的一个实例]”(特别是,任何类都可以用ABC“注册”,以便它将显示为子类,其实例显示为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).

(和ABC还可以通过模板方法设计模式应用程序以非常自然的方式为实际的子类提供额外的便利(有关TM DP的更多信息,请参见此处和[ 此处 [[第II部分]],一般而言,特别是在Python中,独立于ABCs) 。)

For the underlying mechanics of ABC support as offered in Python 2.6, see here ;

(有关Python 2.6中提供的ABC支持的基础机制,请参阅此处 ;)

for their 3.1 version, very similar, see here .

(对于他们的3.1版本,非常相似,请看这里 。)

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.

(在这两个版本中,标准库模块集合 (这是3.1版本 - 非常相似的2.6版本,请参见此处 )提供了几个有用的ABC。)

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.

(为了这个答案的目的,保留关于ABCs的关键(除了可以说更自然的TM DP功能放置,与混合类的经典Python替代方案,如UserDict.DictMixin ),它们是isinstance (和issubclass )比以前更加有吸引力和普遍(在Python 2.6和之前)(在2.5及之前),因此,相比之下,使检查类型相等在最近的Python版本中比以前更糟糕。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...