Тип Python () или __class__, == или

Я хочу проверить, является ли объект экземпляром класса, и только этот класс (без подклассов). Я мог бы сделать это либо с:

obj.__class__ == Foo
obj.__class__ is Foo
type(obj) == Foo
type(obj) is Foo

Есть ли причины выбирать один над другим? (различия в производительности, подводные камни и т. д.)

Другими словами: а) есть ли практическая разница между использованием__class__ а такжеtype(x)? б) всегда ли объекты класса безопасны для сравнения, используяis?

Обновить: Спасибо всем за отзывы. Я все еще озадачен тем, являются ли объекты класса синглетонами, мой здравый смысл говорит, что они есть, но было действительно трудно получить подтверждение (попробуйте поискать в поисках «python», «class» и «unique» или «singleton») ,

Я также хотел бы уточнить, что для моих конкретных потребностей «дешевое» решение, которое просто работает, является лучшим, поскольку я пытаюсь оптимизировать большинство из нескольких специализированных классов (почти до такой степени, что разумное что нужно сделать, это оставить Python и разработать этот конкретный модуль в C). Но причина вопроса заключалась в том, чтобы лучше понять язык, так как некоторые его особенности слишком неясны для меня, чтобы легко найти эту информацию. Вот почему я позволяю дискуссии немного расшириться вместо того, чтобы остановиться на__class__ is, поэтому я могу услышать мнение более опытных людей. Пока это было очень плодотворно!

Я провел небольшой тест для оценки производительности 4 альтернатив. Результаты профилировщика были:

               Python  PyPy (4x)
type()    is   2.138   2.594
__class__ is   2.185   2.437
type()    ==   2.213   2.625
__class__ ==   2.271   2.453

Неудивительно,is лучше, чем== для всех случаев.type() лучше работает в Python (на 2% быстрее) и__class__ лучше работает в PyPy (на 6% быстрее). Интересно отметить, что__class__ == лучше работает в PyPy, чемtype() is.

Обновление 2: многие люди, кажется, не понимают, что я имею в виду, когда «класс - это одиночка», поэтому я проиллюстрирую на примере:

>>> class Foo(object): pass
...
>>> X = Foo
>>> class Foo(object): pass
...
>>> X == Foo
False
>>> isinstance(X(), Foo)
False
>>> isinstance(Foo(), X)
False

>>> x = type('Foo', (object,), dict())
>>> y = type('Foo', (object,), dict())
>>> x == y
False
>>> isinstance(x(), y)
False

>>> y = copy.copy(x)
>>> x == y
True
>>> x is y
True
>>> isinstance(x(), y)
True
>>> y = copy.deepcopy(x)
>>> x == y
True
>>> x is y
True
>>> isinstance(x(), y)
True

Неважно, если есть N объектов типаtypeдля данного объекта только один будет его классом, поэтому в этом случае его можно сравнивать для справки. И поскольку сравнение ссылок всегда будет дешевле, чем сравнение значений, я хотел знать, верно ли мое утверждение выше. Я прихожу к выводу, что это так, если кто-то не представит доказательства в обратном.

Ответы на вопрос(4)

Ваш ответ на вопрос