Existe-t-il un moyen simple de déterminer si une variable est une liste, un dictionnaire ou autre chose ? Je reçois un objet en retour qui peut être de l'un ou l'autre type et je dois être capable de faire la différence.
Pour obtenir le type d'un objet, vous pouvez utiliser la fonction intégrée type()
. Si vous passez un objet comme seul paramètre, vous obtiendrez le type de cet objet :
>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True
>>> type({})
<type 'dict'>
>>> type([])
<type 'list'>
Bien entendu, cela fonctionne également pour les types personnalisés :
>>> class Test1 (object):
pass
>>> class Test2 (Test1):
pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True
Notez que type()
ne retournera que le type immédiat de l'objet, mais ne sera pas capable de vous renseigner sur l'héritage de type.
>>> type(b) is Test1
False
Pour cela, vous devez utiliser la fonction isinstance
. Bien entendu, cela fonctionne également pour les types intégrés :
>>> isinstance(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True
isinstance()
est généralement la meilleure façon de s'assurer du type d'un objet car elle accepte également les types dérivés. Donc, à moins que vous n'ayez réellement besoin du type de l'objet (pour quelque raison que ce soit), l'utilisation de isinstance()
est préférable à celle de type()
.
Le second paramètre de isinstance()
accepte également un tuple de types, il est donc possible de vérifier plusieurs types à la fois. isinstance
retournera alors true, si l'objet est de l'un de ces types :
>>> isinstance([], (tuple, list, set))
True
Il serait peut-être plus pythique d'utiliser un bloc try
...except
. De cette façon, si vous avez une classe qui ressemble à une liste ou à un dict, elle se comportera correctement, quel que soit son type réel.
Pour clarifier, la méthode préférée pour "faire la différence" entre les types de variables est ce qu'on appelle le [duck typing][1] : tant que les méthodes (et les types de retour) auxquelles répond une variable correspondent à ce que votre sous-programme attend, traitez-la comme ce que vous attendez d'elle. Par exemple, si vous avez une classe qui surcharge les opérateurs de crochets avec getattr
et setattr
, mais qui utilise un drôle de schéma interne, il serait approprié qu'elle se comporte comme un dictionnaire si c'est ce qu'elle essaie d'émuler.
L'autre problème avec la vérification de type(A) is type(B)
est que si A
est une sous-classe de B
, il évalue à false
alors que, programmatiquement, vous espérez que ce soit true
. Si un objet est une sous-classe d'une liste, il devrait fonctionner comme une liste : vérifier le type comme présenté dans l'autre réponse empêchera cela. (isinstance
fonctionnera cependant).