Сравнение двух типов классов в python

у меня есть два класса, определенные в модуле 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 ответов


объяснение

вот почему ваше сравнение не работает так, как ожидалось

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

а зачем ClassA и ClassB иметь тот же тип 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'.

Если вы просто хотите сравнить классы, сравнивать их напрямую:

print Class3 == Class4

В дополнение к другим ответы :

Python использует концепцию метаклассов, которые в основном являются "классами классов". Это означает, что даже класс является объектом в Python, который имеет свой собственный класс, доступный с помощью type функция in-build.

, потому что ClassA и ClassB по умолчанию являются экземплярами одного и того же метакласса, сравнения возвращают True.

Если вы хотите узнать больше о метаклассы, это так пост - это хорошо начать.


если вы хотите проверить, равны ли типы, то вы должны использовать 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, в то время как следующая проверка возвращается ожидалось True стоимостью

StupidClass is StupidClass

так, как мы можем видеть == оператор может быть переопределен, пока нет простого способа изменить оператора.