【问题标题】:How to compare type of an object in Python?如何在 Python 中比较对象的类型?
【发布时间】:2010-10-16 23:59:05
【问题描述】:

基本上我想这样做:

obj = 'str'
type ( obj ) == string

我试过了:

type ( obj ) == type ( string )

它没有用。

另外,其他类型呢?例如,我无法复制NoneType

【问题讨论】:

  • 这工作type(obj) == str

标签: python types compare


【解决方案1】:
isinstance()

在您的情况下,isinstance("this is a string", str) 将返回 True

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

【讨论】:

  • 我会说你(OP)应该肯定阅读引用的链接,它提供了很多细节说明为什么检查对象的类型通常是一个坏主意,以及您可能应该做的事情。
  • 你应该使用 basestr,而不是 str。否则你不会选择unicode。 (尽管对于 3.x,我认为 str basestr)
【解决方案2】:

isinstance 工作:

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

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

编辑:对于 None 类型,您可以简单地这样做:

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”。如何解决这个问题?
  • 如果你想使用 isinstance 但也要检查 None 然后 isinstance(obj, (MyClass, type(None))) 有效。 types.NoneType 已从 Python 3 中删除,因此它不像 type(None) 那样可移植以获取对 NoneType 的引用。
【解决方案3】:

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

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

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 对象是一个单例。只需检查无

variable is None

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

【讨论】:

  • 如果您正在验证来自 DSL 的输入,您需要所有这些,即使是 NoneType。如果参数可以是strunicodeNone,该怎么办? isinstance(x, (str, unicode, types.NoneType)) 比检查 None 要干净得多。如果您正在构建用于延迟计算的工具,或者如果您要启动一个长期或资源密集型流程,那么在一些自定义验证步骤中提前捕获type 错误是很有价值的。这几乎是我从事过的每一个科学计算项目的关键部分。在我见过的所有开发项目中,需要这个的比不需要的多。
【解决方案4】:

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

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

附:类型检查是个坏主意。

【讨论】:

    【解决方案5】:

    您始终可以使用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
    

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

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

    【讨论】:

    • 不管怎样,isinstance() 是在 Python 中检查类型的首选方法(当你必须这样做时)。
    【解决方案6】:

    你非常接近! string 是一个模块,而不是一个类型。您可能希望将obj 的类型与字符串的类型对象(即str)进行比较:

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

    或者:

    type(obj) == type('')
    

    注意,在 Python 2 中,如果 obj 是 unicode 类型,那么以上都不起作用。 isinstance() 也不会。请参阅这篇文章的 John 的 cmets,了解如何解决这个问题……我已经尝试记住它大约 10 分钟了,但记忆力受阻!

    【讨论】:

    • 使用 basestring 和 isinstance() 来获取 str 和 unicode。
    【解决方案7】:

    用str代替字符串

    type ( obj ) == str
    

    解释

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

    【讨论】:

      【解决方案8】:

      使用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 
      

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

      【讨论】:

        【解决方案9】:

        因为你要写

        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() 调用之前引发异常。如果没有接口检查,您将删除该文件,然后引发异常。

        【讨论】:

        • 感谢您指出检查接口的实际首选方法。这里的许多答案都提到了它,但很少有人举例说明什么是好的。它仍然没有直接回答我的个人问题(我正在尝试将包含许多有意义的项目的字符串列表与包含许多无意义的项目的字符串分开。谢谢!
        【解决方案10】:

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

        例如,如果我想检查一个数组:

        type( x ) == type( [] )
        

        字符串检查:

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

        如果要检查 None,请使用 is

        x is None
        

        【讨论】:

        • 嗯?为什么一般来说这是一个坏主意?对于字符串(对于 3.0 之前的版本)来说,这只是一个坏主意,因为字符串有两种类型,str 和 unicode。对于数组,恕我直言,这是个好主意。
        • @hasen:总的来说这是个坏主意。如果我定义自己的类型,它的行为类似于数组,但从数据库中获取值怎么办?您的代码将无缘无故地因我的类型而失败。
        • @hasen:阅读 voltronw 投票最多 (+7) 答案的链接canonical.org/~kragen/isinstance
        • 嗯,检查类型的全部原因(至少对我而言)正是因为我想以不同于其他类型(包括模仿数组的类型)的方式处理数组。
        • 你错了。我会给你一个具体的例子:django 有一个模板渲染快捷方式,它可以接受一个字符串或一个字符串数组。现在,字符串和数组(列表)都是可迭代的,但在这种情况下,函数需要区分它们。
        【解决方案11】:

        我认为应该这样做

        if isinstance(obj, str)
        

        【讨论】:

          【解决方案12】:

          Type 不适用于某些类。如果您不确定对象的类型,请使用__class__ 方法,如下所示:

          >>>obj = 'a string'
          >>>obj.__class__ == str
          True
          

          另见这篇文章 - http://www.siafoo.net/article/56

          【讨论】:

            【解决方案13】:

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

            在这里谈论鸭式打字毫无用处,因为它不能回答一个完美的问题。在我的应用程序代码中,我从不需要知道某物的类型,但是有一种方法来学习对象的类型仍然很有用。有时我需要获取实际的类来验证单元测试。因为所有可能的对象都具有相同的 API,但只有一个是正确的,所以鸭子类型会妨碍那里。另外,有时我在维护别人的代码,我不知道我传递了什么样的对象。这是我对 Python 等动态类型语言的最大问题。版本 1 开发起来非常简单快捷。版本 2 是个麻烦事,特别是如果你没有编写版本 1。所以有时,当我使用我没有编写的函数时,我需要知道参数的类型,所以我知道我可以调用什么方法。

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

            【讨论】:

              【解决方案14】:

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

              #!/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
              

              【讨论】:

                猜你喜欢
                • 2011-09-25
                • 2023-03-11
                • 2021-11-08
                • 1970-01-01
                • 2010-10-17
                • 2018-05-08
                • 1970-01-01
                • 2014-06-13
                • 2018-01-21
                相关资源
                最近更新 更多