Python type () o __class__, == o es

Quiero probar si un objeto es una instancia de una clase, y solo esta clase (sin subclases). Podría hacerlo con:

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

¿Hay razones para elegir uno sobre otro? (diferencias de rendimiento, dificultades, etc.)

n otras palabras: a) ¿hay alguna diferencia práctica entre usar__class__ ytype(x)? b) ¿son los objetos de clase siempre seguros para la comparación usandois?

Actualizar Gracias a todos por los comentarios. Todavía estoy desconcertado por si los objetos de clase son singletons o no, mi sentido común dice que lo son, pero ha sido muy difícil obtener una confirmación (intente buscar en Google "python", "class" y "unique" o "singleton") .

También me gustaría aclarar que, para mis necesidades particulares, la solución "más barata" que simplemente funciona es la mejor, ya que estoy tratando de optimizar al máximo algunas clases especializadas (casi llegando al punto en que Lo más sensato es soltar Python y desarrollar ese módulo en particular en C). Pero la razón detrás de la pregunta era entender mejor el lenguaje, ya que algunas de sus características son demasiado oscuras para que pueda encontrar esa información fácilmente. Es por eso que dejo que la discusión se extienda un poco en lugar de conformarme con__class__ is, así puedo escuchar la opinión de personas más experimentadas. ¡Hasta ahora ha sido muy fructífero!

Realicé una pequeña prueba para comparar el rendimiento de las 4 alternativas. Los resultados del perfilador fueron:

               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

orprendentemente,is funcionó mejor que== para todos los casos. @type() funcionó mejor en Python (2% más rápido) y__class__ funcionó mejor en PyPy (6% más rápido). Interesante notar que__class__ == funcionó mejor en PyPy quetype() is.

Actualización 2: muchas personas no parecen entender lo que quiero decir con "una clase es un singleton", así que ilustraré con un ejemplo:

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

No importa si hay N objetos de tipotype, dado un objeto, solo uno será su clase, por lo tanto, es seguro compararlo como referencia en este caso. Y dado que la comparación de referencias siempre será más barata que la comparación de valores, quería saber si mi afirmación anterior es válida o no. Estoy llegando a la conclusión de que sí, a menos que alguien presente evidencia en contrario.

Respuestas a la pregunta(8)

Su respuesta a la pregunta