如何在Python中比较对象的类型?


Answers:


241
isinstance()

就您而言,isinstance("this is a string", str)将返回True

您可能还需要阅读以下内容:http : //www.canonical.org/~kragen/isinstance/


4
我想说您(OP)一定要阅读引用的链接,该链接提供了很多详细信息,说明为什么检查对象的类型通常是个坏主意,以及您可能应该做的事情。
杰夫·香农(

2
您应该使用basestr,而不是str。否则,您将不会选择unicode。(尽管对于3.x,我认为str basestr)
hasen

36

isinstance 作品:

if isinstance(obj, MyClass): do_foo(obj)

但是请记住:如果它看起来像鸭子,听起来像鸭子,那就是鸭子。

编辑:对于无类型,您可以简单地做:

if obj is None: obj = MyClass()

def distance_from_zero(n): if isinstance(n,int) or isinstance(n,float): return abs(n) else: return "Nope" print distance_from_zero(True) 这将返回“ 1”而不是“ Nope”。如何解决这个问题?
dig_123

如果你想使用isinstance也检查None,然后isinstance(obj, (MyClass, type(None)))作品。types.NoneType已从Python 3中删除,因此它不像type(None)引用那样可移植NoneType
Santeri Paavolainen

33

首先,避免所有类型的比较。它们非常非常必要。有时,它们有助于检查函数中的参数类型-即使这种情况很少见。错误的类型数据将引发异常,这就是您所需要的。

所有基本转换函数都将映射为等于类型函数。

type(9) is int
type(2.5) is float
type('x') is str
type(u'x') is unicode
type(2+3j) is complex

还有其他一些情况。

isinstance( 'x', basestring )
isinstance( u'u', basestring )
isinstance( 9, int )
isinstance( 2.5, float )
isinstance( (2+3j), complex )

不用说,顺便说一句,永远不需要这种类型的检查。None是NoneType的唯一实例。None对象是一个Singleton。只需检查无

variable is None

顺便说一句,一般不要使用以上内容。使用普通异常和Python自己的自然多态性。


3
如果您要验证来自DSL的输入,则甚至需要NoneType。如果一个参数可以是一个strunicode或者Noneisinstance(x, (str, unicode, types.NoneType))比检查是否干净得多None。如果您要构建用于延迟计算的工具,或者要启动一个漫长的过程或占用大量资源的过程,那么type在某些自定义验证步骤中提前发现错误是很有价值的。这一直是我从事过的几乎所有科学计算项目的关键部分。在我见过的所有开发项目中,有更多需要而不是没有。
2014年

23

对于其他类型,请检查类型模块:

>>> import types
>>> x = "mystring"
>>> isinstance(x, types.StringType)
True
>>> x = 5
>>> isinstance(x, types.IntType)
True
>>> x = None
>>> isinstance(x, types.NoneType)
True

PS类型检查不是一个好主意。


15

您总是可以使用type(x) == type(y)把戏,哪里y是已知类型的东西。

# check if x is a regular string
type(x) == type('')
# check if x is an integer
type(x) == type(1)
# check if x is a NoneType
type(x) == type(None)

通常,有更好的方法可以做到这一点,尤其是使用任何最新的python。但是,如果您只想记住一件事,则可以记住。

在这种情况下,更好的方法是:

# check if x is a regular string
type(x) == str
# check if x is either a regular string or a unicode string
type(x) in [str, unicode]
# alternatively:
isinstance(x, basestring)
# check if x is an integer
type(x) == int
# check if x is a NoneType
x is None

请注意最后一种情况:NoneTypepython中只有一个实例,即None。您会在异常中看到很多NoneType(TypeError: 'NoneType' object is unsubscriptable -一直在我身上发生..),但是您几乎不需要在代码中引用它。

最后,正如fengshaun指出的那样,在python中进行类型检查并不总是一个好主意。只使用该值,就像它是您期望的类型一样,并捕获(或允许传播)由此产生的异常,这是更Python风格的。


1
对于它的价值,isinstance()是检查Python中类型的首选方法(必要时)。
David Z

6

你很亲密!string是模块,而不是类型。您可能要比较obj字符串的type对象和type对象的类型,即str

type(obj) == str  # this works because str is already a type

或者:

type(obj) == type('')

请注意,在Python 2中,如果obj是unicode类型,则以上两种都不起作用。也不会isinstance()。有关此问题的解决方法,请参见John对这篇文章的评论。我一直在想起它大约10分钟,但是有一个内存块!


2
将basestring与isinstance()一起使用可获取str和unicode。
John Fouhy

5

因为你必须写

s="hello"
type(s) == type("")

type接受实例并返回其类型。在这种情况下,您必须比较两个实例的类型。

如果需要进行抢先检查,则检查受支持的接口比类型更好。

除了您的代码需要特定类型的实例这一事实之外,该类型实际上并不能告诉您太多信息,无论您是否可以拥有另一个完全不同类型的实例(因为它实现了相同的接口),这完全可以了。 。

例如,假设您有此代码

def firstElement(parameter):
    return parameter[0]

现在,假设您说:我希望这段代码仅接受一个元组。

import types

def firstElement(parameter):
    if type(parameter) != types.TupleType:
         raise TypeError("function accepts only a tuple")
    return parameter[0]

这降低了此例程的可重用性。如果您传递列表,字符串或numpy.array,则将无法使用。更好的是

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    return parameter[0]

但是这样做没有任何意义:如果无论如何都不满足协议,则parameter [0]会引发异常……这当然是除非您想防止副作用或必须从失败之前可以调用的调用中恢复过来。(愚蠢的)示例,只是为了说明这一点:

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    os.system("rm file")
    return parameter[0]

在这种情况下,您的代码将在运行system()调用之前引发异常。如果不进行接口检查,则将删除该文件,然后引发异常。


感谢您指出检查接口的实际首选方法。这里有很多答案都提到了它,但是很少有例子说明它有什么好处。它仍然不能直接回答我的个人问题(我试图将包含许多有意义的项目的字符串列表与包含许多没有意义的项目的字符串分开。谢谢!
Nick

5

使用str代替字符串

type ( obj ) == str

说明

>>> a = "Hello"
>>> type(a)==str
True
>>> type(a)
<type 'str'>
>>>

4

我用 type(x) == type(y)

例如,如果我要检查的东西是一个数组:

type( x ) == type( [] )

字符串检查:

type( x ) == type( '' ) or type( x ) == type( u'' )

如果要检查无,请使用

x is None

?? 为什么总的来说这是个坏主意?对于字符串(3.0之前的版本)来说,这只是一个坏主意,因为存在两种类型的字符串,即str和unicode。对于数组,恕我直言是个好主意。
hasen

@hasen:总的来说这是一个坏主意。如果我定义自己的类型就像数组一样,但是从数据库中获取值怎么办?您的代码将无缘无故失败。
nosklo

@hasen:阅读链接canonical.org/~kragen/isinstance投票最多的(+7)答案,作者voltronw
nosklo

1
好吧,检查类型的整个原因(对我来说至少是)完全是因为我想与其他类型(包括模仿数组的类型)不同地处理数组。
hasen 2009年

2
你错了。我给你一个具体的例子:django有一个模板渲染快捷方式,可以接受一个字符串或一个字符串数组。现在,字符串和数组(列表)都是可迭代的,但是在这种情况下,函数需要区分它们。
hasen



2

要获取类型,请使用__class__成员,如下所示unknown_thing.__class__

在这里说鸭嘴式是没有用的,因为它不能回答一个完美的问题。在我的应用程序代码中,我永远不需要知道某种事物的类型,但是有一种学习对象类型的方法仍然很有用。有时我需要获得实际的课程来验证单元测试。因为所有可能的对象都具有相同的API,但只有一个是正确的,因此鸭子类型会妨碍您的输入。另外,有时我正在维护其他人的代码,而且我不知道我传递了什么样的对象。这是诸如Python之类的动态类型语言的最大问题。版本1非常易于开发。第2版​​让您不知所措,尤其是如果您没有编写第1版时。因此,有时候,当我使用未编写的函数时,我需要知道参数的类型,

那就是__class__参数派上用场的地方。(据我所知)这是获取对象类型的最佳方法(也许是唯一方法)。


2

使用isinstance(object, type)。如上所述,如果您知道正确的方法type,这很容易使用,例如,

isinstance('dog', str) ## gives bool True

但是对于更深奥的物体,这可能很难使用。例如:

import numpy as np 
a = np.array([1,2,3]) 
isinstance(a,np.array) ## breaks

但您可以执行以下操作:

y = type(np.array([1]))
isinstance(a,y) ## gives bool True 

因此,我建议y使用要检查的对象类型(例如type(np.array()))实例化变量(在这种情况下),然后使用isinstance


0

您可以比较检查级别的类。

#!/usr/bin/env python
#coding:utf8

class A(object):
    def t(self):
        print 'A'
    def r(self):
        print 'rA',
        self.t()

class B(A):
    def t(self):
        print 'B'

class C(A):
    def t(self):
        print 'C'

class D(B, C):
    def t(self):
        print 'D',
        super(D, self).t()

class E(C, B):
    pass

d = D()
d.t()
d.r()

e = E()
e.t()
e.r()

print isinstance(e, D) # False
print isinstance(e, E) # True
print isinstance(e, C) # True
print isinstance(e, B) # True
print isinstance(e, (A,)) # True
print e.__class__ >= A, #False
print e.__class__ <= C, #False
print e.__class__ <  E, #False
print e.__class__ <= E  #True
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.