如何在Python中比较两个类/类型?

13

我有两个类在一个名为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原生类型值比较类类型?

4个回答

18

说明

这就是为什么您的比较结果不如预期的原因。

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

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

默认情况下,使用type()构建类。类体在新命名空间中执行,并将类名本地绑定到type(name,bases,namespace)的结果。

示例:

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

顺带一提,你也可以在类中使用is代替==


谢谢,但初始化不是一个选项。 - E.Beach
@E.Beach 我预料到了,所以我已经添加了一种比较它们而不需要初始化的方法。 - vaultah
@E.Beach 无论如何,我添加了额外的解释。 - vaultah
到目前为止,这是我见过的最好的例子!感谢您省略了不必要的类体等内容。 - NoName

10
如果要检查类型是否相等,应该使用is运算符例如:我们可以创建下一个愚蠢的元类。
class StupidMetaClass(type):
    def __eq__(self, other):
        return False

然后可以基于它创建类:

  • in Python 2

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

    class StupidClass(metaclass=StupidMetaClass):
         pass
    
    
然后进行简单的检查。
>>> StupidClass == StupidClass

返回 False,而

>>> StupidClass is StupidClass

返回一个预期的True值。

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


3

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

如果只想比较类,请直接进行比较:

print Class3 == Class4

1
除了其他答案之外:
Python使用元类的概念,这些元类基本上是“类的类”。这意味着,即使一个类在Python中也是一个对象,它有自己的类 - 可以使用内置函数type来访问。
因为ClassAClassB默认情况下是相同元类的实例,所以比较返回True。
如果您想了解更多关于元类的知识,这个SO帖子是一个很好的开始。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接