【问题标题】:How to compare two classes/types in python?如何比较python中的两个类/类型?
【发布时间】:2014-05-25 14:01:56
【问题描述】:

我在模块classes.py 中定义了两个类:

class ClassA(object):
    pass

class ClassB(object):
    pass

在另一个模块中,我得到了模块的属性:

import classes

Class1 = getattr(classes, 'ClassA')
Class2 = getattr(classes, 'ClassA')
print type(Class1) == type(Class2)

Class3 = getattr(classes, 'ClassA')
Class4 = getattr(classes, 'ClassB')
print type(Class3) == type(Class4)

两种类型比较都返回 True,这不是我所期望的。

如何使用 python 的原生类型值比较类类型?

【问题讨论】:

    标签: python types


    【解决方案1】:

    您正在比较类对象的类型,它们都是'type' 类型。

    如果只想比较类,直接比较:

    print Class3 == Class4
    

    【讨论】:

      【解决方案2】:

      说明

      这就是您的比较没有按预期进行的原因

      >>> class ClassA(object):
      ...     pass
      ... 
      >>> class ClassB(object):
      ...     pass
      ... 
      >>> type(ClassB)
      <class 'type'> 
      >>> type(ClassA)
      <class 'type'> 
      >>> type(ClassA) == type(ClassB)
      True
      

      但是为什么ClassAClassB 有相同的类型type?引用docs

      默认情况下,类是使用 type() 构造的。类体是 在新的命名空间中执行,并且类名在本地绑定到 类型(名称、基数、命名空间)的结果。

      例子:

      >>> ClassB
      <class '__main__.ClassB'>
      >>> type('ClassB', (), {})
      <class '__main__.ClassB'>
      >>> type(ClassB)
      <class 'type'>
      >>> type(type('ClassB', (), {}))
      <class 'type'>
      

      获取ClassB的类型与获取type('ClassB', (), {})的类型完全相同,即type

      解决方案

      直接比较它们(不使用type()函数):

      >>> ClassA
      <class '__main__.ClassA'>
      >>> ClassB
      <class '__main__.ClassB'>
      >>> ClassA == ClassB
      False
      

      或初始化它们并比较它们的对象类型:

      >>> a = ClassA()
      >>> b = ClassB()
      >>> type(a) 
      <class '__main__.ClassA'>
      >>> type(b) 
      <class '__main__.ClassB'>
      >>> type(a) == type(b)
      False
      

      FWIW,您也可以使用 is 代替 ==(用于课程)。

      【讨论】:

      • 谢谢,但初始化不是一个选项。
      • @E.Beach 我预料到了,所以我添加了在不初始化的情况下比较它们的方法。
      • @E.Beach 无论如何,添加了额外的解释
      • 迄今为止我见过的最好的例子!感谢您省略了类主体等不必要的内容。
      【解决方案3】:

      除了其他答案:

      Python 使用元类的概念,它基本上是“类的类”。这意味着,即使是一个类也是 Python 中的一个对象,它有自己的类 - 可以使用 type in-build 函数访问。

      因为ClassAClassB 默认情况下是同一个元类的实例,所以比较返回True。

      如果您想了解有关元类的更多信息,this SO post 是一个好的开始。

      【讨论】:

        【解决方案4】:

        如果你想检查类型是否相等,那么你应该使用is操作符

        示例:我们可以创建下一个愚蠢的元类

        class StupidMetaClass(type):
            def __eq__(self, other):
                return False
        

        然后基于它进行分类:

        • 在 Python 2 中

            class StupidClass(object):
                __metaclass__ = StupidMetaClass
          
        • 在 Python 3 中

          class StupidClass(metaclass=StupidMetaClass):
               pass
          
          

        然后是一个简单的检查

        >>> StupidClass == StupidClass
        

        返回False,而

        >>> StupidClass is StupidClass
        

        返回预期的True 值。

        所以我们可以看到 == 类上的运算符可以重载,而没有办法(至少是简单的一种)来改变 is 运算符的行为。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-01-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多