type en Python : connaître la nature d'une valeur

type révèle la nature exacte d'une valeur Python. Un outil de diagnostic, à distinguer d'isinstance qui, lui, sert à décider.
5 min de lecture
Believemy logo

Définition

Une valeur arrive dans le code sans étiquette. Elle vient d'un fichier, d'une saisie clavier, ou du retour d'une fonction écrite par quelqu'un d'autre, et rien n'indique à l'œil nu si elle se comporte comme un nombre, un texte ou une liste. Tant que cette nature reste incertaine, une opération d'apparence anodine peut échouer, ou pire, réussir en donnant un résultat faux. type répond à cette incertitude : appelée avec une valeur, la fonction renvoie la classe à laquelle elle appartient, ce qui suffit à trancher sans deviner ni relire le code qui l'a produite.

Trois exemples suffisent à voir la fonction à l'œuvre, sur un nombre, un texte et une liste :

PYTHON
print(type(7))
# <class 'int'>

print(type("7"))
# <class 'str'>

print(type([7]))
# <class 'list'>

Ce qui revient n'est pas du texte mais un objet à part entière, la classe elle-même. Cette distinction a une conséquence concrète : type(7) is int vaut True, car la comparaison porte sur deux objets identiques en mémoire, et non sur deux mots qui se ressembleraient à l'écriture.


Les types croisés chaque jour

Un message d'erreur mentionne presque toujours un de ces noms au passage, NoneType, dict, str. Le reconnaître du premier coup évite d'aller chercher sa signification ailleurs. Le tableau qui suit rassemble les types qui reviennent le plus souvent dans du code Python ordinaire, avec ce que chacun représente.

ValeurType renvoyéCe qu'elle représente
42intUn entier, pour compter et mesurer
3.5floatUn float, avec des décimales
"bonjour"strUne chaîne de caractères
[1, 2]listUne liste modifiable
(1, 2)tupleUne séquence figée
{"a": 1}dictUn dictionnaire, lu par clé
TrueboolUn bool, vrai ou faux
NoneNoneTypeL'absence de valeur, None

Le tableau se lit aussi à l'envers : chacun de ces noms est en même temps une fonction de construction. int("42") transforme un texte en nombre, str(42) fait l'inverse, et list("abc") éclate une chaîne en liste de caractères. Une seule famille de mots sert donc à la fois à identifier une valeur et à en fabriquer une.


Diagnostiquer au lieu de deviner

Dans du code livré, cette fonction sert rarement à écrire une condition. Son terrain, c'est l'instant où un calcul produit un résultat qui n'a aucun sens. Le réflexe utile est alors de regarder la nature exacte des valeurs en jeu, car l'erreur que Python affiche arrive souvent plusieurs lignes après l'endroit où le problème est né, sur une opération qui n'y est pour rien.

Voici une situation fréquente chez qui débute :

PYTHON
quantite = input("Combien ? ")
print(type(quantite))
# <class 'str'>

total = quantite * 3
# "222" au lieu de 6

Le coupable ici est input, qui renvoie toujours du texte, même lorsque la personne tape des chiffres. La multiplication ne plante pas, elle répète la chaîne trois fois, et l'erreur se propage en silence jusqu'à l'affichage final. Un appel à type posé juste après la saisie tranche la question en une seconde, là où relire tout le calcul peut prendre une heure.


Observer avec type, décider avec isinstance

Reste une question : comment orienter un traitement selon la nature d'une valeur ? Malgré la tentation, ce n'est pas le rôle de type. Le bon outil pour décider est isinstance, car il tient compte de l'héritage là où la comparaison stricte l'ignore complètement.

La différence se voit sur une classe qui hérite d'un type existant, comme un panier qui hérite d'un dictionnaire :

PYTHON
class Panier(dict):
    pass

p = Panier()

isinstance(p, dict)   # True
type(p) is dict       # False

Un objet dérivé d'une classe reste un exemplaire de sa classe parente, alors que son type exact, lui, a changé : les deux lignes ne donnent donc pas la même réponse.

Attention

bool hérite de int en Python. isinstance(True, int) vaut donc True, ce qui piège quiconque teste une valeur en croyant exclure les booléens : un True glissé dans une liste de nombres passe le test sans être repéré.

En pratique, cette fonction sert à observer pendant la mise au point, tandis qu'isinstance sert à décider une fois le code livré. Elle accepte d'ailleurs plusieurs candidats à la fois, comme isinstance(valeur, (int, float)), ce qui couvre les deux familles numériques en une seule condition.


Questions fréquentes

Question

Comment obtenir seulement le nom du type ?

En lisant l'attribut __name__ de la classe renvoyée : type(valeur).__name__ donne la chaîne "int" plutôt que la représentation complète entre chevrons. C'est la forme à privilégier dans un message d'erreur destiné à être lu par quelqu'un.

Question

Que fait cette fonction appelée avec trois arguments ?

Elle ne lit plus un type existant, elle en crée un nouveau : type("Point", (), {}) fabrique une classe nommée Point, sans parent ni contenu. Cette forme sert au code qui génère des classes à la volée, et rappelle qu'en Python une classe est une valeur comme une autre.

Question

Faut-il vérifier la nature de chaque argument reçu ?

Non, la culture du langage préfère essayer puis rattraper avec try plutôt que vérifier avant d'agir. Le contrôle systématique alourdit le code et rejette parfois des valeurs qui se seraient bien comportées. Une vérification garde son intérêt aux frontières du programme, sur une donnée venue d'un fichier ou du réseau. Comprendre quand Python convertit tout seul et quand il refuse évite la moitié des erreurs des débuts, un terrain que couvre notre formation Python.

Termes connexes

Découvrez notre glossaire Python

Parcourez les termes et définitions les plus couramment utilisés dans le domaine du développement avec Python.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.