¿Determinar el tipo de un objeto?

¿Existe una forma sencilla de determinar si una variable es una lista, un diccionario o algo más? Estoy recibiendo un objeto de vuelta que puede ser de cualquier tipo y necesito ser capaz de decir la diferencia.

Solución

Para obtener el tipo de un objeto, puede utilizar la función incorporada type(). Pasando un objeto como único parámetro devolverá el tipo de ese objeto:

>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True
>>> type({})

>>> type([])

Esto, por supuesto, también funciona para los tipos personalizados:

>>> class Test1 (object):
        pass
>>> class Test2 (Test1):
        pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True

Tenga en cuenta que type() sólo devolverá el tipo inmediato del objeto, pero no podrá informarle sobre la herencia de tipos.

>>> type(b) is Test1
False

Para cubrir eso, deberías usar la función isinstance. Esto, por supuesto, también funciona para los tipos incorporados:

>>> isinstance(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True

isinstance() suele ser la forma preferida de asegurar el tipo de un objeto porque también acepta tipos derivados. Así que, a menos que necesites el tipo del objeto (por la razón que sea), es preferible usar isinstance() que type().

El segundo parámetro de isinstance() también acepta una tupla de tipos, por lo que es posible comprobar varios tipos a la vez. isinstance devolverá entonces true, si el objeto es de alguno de esos tipos:

>>> isinstance([], (tuple, list, set))
True
Comentarios (16)

Puedes hacerlo utilizando type():

>>> a = []
>>> type(a)

>>> f = ()
>>> type(f)
Comentarios (0)

Podría ser más Pythonico usar un bloque try...except. De esta manera, si tienes una clase que se parece a una lista, o se parece a un dict, se comportará correctamente independientemente de cuál sea su tipo realmente.

Para aclarar, el método preferido para "distinguir" entre tipos de variables es algo llamado duck typing: mientras los métodos (y tipos de retorno) a los que responde una variable sean los que espera tu subrutina, trátala como lo que esperas que sea. Por ejemplo, si tienes una clase que sobrecarga los operadores de corchetes con getattr y setattr, pero utiliza algún esquema interno gracioso, sería apropiado que se comportara como un diccionario si eso es lo que está tratando de emular.

El otro problema con la comprobación type(A) is type(B) es que si A es una subclase de B, se evalúa como false cuando, programáticamente, se esperaría que fuera true. Si un objeto es una subclase de una lista, debería funcionar como una lista: la comprobación del tipo como se presenta en la otra respuesta lo evitará. (Sin embargo, isinstance funcionará).

Comentarios (2)