E.Beach E.Beach - 5 months ago 18
Python Question

Comparing two class types in python

I have two classes defined in a module

classes.py
:

class ClassA(object):
pass

class ClassB(object):
pass


And in another module I am getting the attributes of the module:

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)


Both type comparison are returning True and that's not what I was expecting.

How can I compare class types using python's native type values?

Answer Source

Explanation

This is why your comparison doesn't work as expected

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

But why do ClassA and ClassB have the same type type? Quoting the docs:

By default, classes are constructed using type(). The class body is executed in a new namespace and the class name is bound locally to the result of type(name, bases, namespace).

Example:

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

Getting the type of ClassB is exactly the same as getting the type of type('ClassB', (), {}), which is type.

Solutions

Compare them directly (w/out using the type() function):

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

or initialize them and compare the types of their objects:

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

FWIW you can also use is in place of == (for classes).