Quelle est le rôle de la fonction **id** en Python ?
Tags: python, programming
Published: 2024-03-24 15:47:20

## Définition

Par définition, les variables sont des façon imagée des cases dans lesquelles Python va stocker des valeurs identifiées par une étiquette appelée nom de variable.



![Etagère](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/31fvtl1hg0wfalndjvld.jpg)
[Source Image](https://unsplash.com/fr/photos/gros-plan-dun-tiroir-rouge-avec-des-chiffres-dessus-Z43SnJD0rrQ)

Si la mémoire de l'ordinateur était représentée comme une étagère avec plusieurs tiroirs numéroté, la valeur d'une variable sera stockée dans un des tiroirs.

Le rôle de *id* en Python permettra de renvoyer le numéro de la case mémoire où est stockée la valeur de la variable.

Pour utiliser **id** on utilise le format suivant: `id(nom_variable)`. Par exemple:


![Exemple utilisation de id](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m6z11b8t0rbvk53qira3.png)

Dans l'exemple précédent on voit que les variable *a* et *b* ont un numéro de case mémoire différent ce qui signifie que les valeurs des variables sont stockées dans des cases mémoire différentes.

**La fonction id ne renvoie pas tout le temps le même numéro de case mémoire. La valeur obtenue varie d'un ordinateur à l'autre.**

Quand on écrit un programme en Python pour les type primitifs comme **int**(entier), **float**(nombre à virgule), **bool**(booléen) et les types **str**(chaine) lorsque deux variables ont la même valeur, les deux variables partage la même case mémoire tant que la valeur est identique. Comme dans les exemples ci dessous:


![Exemple id sur les ints](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3oa7vhailhyl8cfamou.png)

Le même résultat est obtenu avec les **strings** type **str**.


![Exemple id sur les types chaines](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z089x2kpcsjmyjwmqc0n.png)

**Ce mécanisme de partage de la même case mémoire n'augmente pas la mémoire occupée par une variable. 100 variables ayant la même valeur et 50 variables ayant la même valeur sont liée à une seule case mémoire.**

Cependant cela n'est plus pareil pour les types **Objets** comme les **list**(liste), **tuple** et les **dict**(dictionnaires). Toute déclaration d'une variable de type objet sera stockée dans une nouvelle case mémoire peut importe qu'une autre variable existe ou non.


![Exemple sur les types objets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/56ok4qb2iwu5d9nmhizq.png)

**Contrairement aux types primitifs ici on a une augmentation de la mémoire occupée. 100 variables de type objet occuperont 100 cases mémoires différentes.**

Quand on utilise l'opération **=** pour assigner une variable à une autre c'est  la copie de la case mémoire qui est faite. **a=b** signifie assigne aux variables **a** et **b** la même case mémoire qui est celle de **b**. Vue que la case mémoire est pareille dans le cas des listes cela revient à manipuler la même liste.


![Exemple d'utilisation d'égalité](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lx3tlfm5ly0zp8p63c7.png)

## Subtilité avec input

Quand l'utilisateur entre dans le jeu cela change.

Précédemment pour les types primitifs, **id** renvoyait la même valeur parce les variables contenaient les mêmes valeurs. Quand on utilise la fonction **input** qui permet à l'utilisateur de saisir une valeur, la valeur saisie de l'utilisateur est stockée dans une nouvelle case mémoire.


![Exemple sur les mutations](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4evfg57jlnd2bhipuf2.png)

Quand l'utilisateur doit saisir une nombre la saisie est stockée dans une nouvelle case mémoire car on ne sait pas si ce que va fournir l'utilisateur est une valeur déjà stockée ou non.

Après saisie de l'utilisateur si on convertit et qu'on a la même valeur qu'une déjà stockée, l'identifiant devient celui de la valeur actuellement stockée on parle de **mutation**.

**Ce mécanisme de mutation ne fonctionne pas avec les chaines de caractères ni avec les types objets.**

Quand il s'agit du type **str** la case mémoire où la valeur de l'utilisateur est stockée ne changera pas même si la même valeur existe déjà c'est pourquoi on dit que les chaine de caractères **str** sont **immuables** car leur **id** ne change plus quand déjà alloué.


![Exemple sans mutation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7f0olcc6xvn7e8kyx8v8.png)

## Subtilité des comparaisons avec *is* et *is not*

Il existe en Python les mots clés **is not** et **is** qui sont utilisés par certains programmeurs (moi y compris je suis tombé dans le piège d'où l'objet de l'article) parfois à tort pour vérifier si une deux variables ont la même valeur.

Cependant cette méthode n'est pas du tout la même chose quand on parle des types complexes comme les **string** (chaines de caractères).

En réalité les mots clés **is** et **is not** font une comparaison des cases mémoire c'est à dire du résultat des valeurs de **id** pas des valeurs des variables.

Ces mots clés vérifient que deux variables sont stockées dans la même case mémoire. Pour comparer les valeurs on utilisera **==** et **!=** quand on parle des chaines.


![Exemple is sur les types entiers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xb9qj0qedjnjrvbobx1b.png)

***==* et *!=* sur les types primitifs sont identiques que *is* et *is not*.**

Sur les chaines c'est plus pareil.


![Exemple is sur les types chaines](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1dy3p7d4gxjx9cq4ifu5.png)

Pour résumer:

+ **is** et **is not** donne le même résultat que **!=** et **==** pour les variables de types simples car ces valeurs sont mutables, les identifiants de case mémoire change quand les valeurs sont identiques. Plusieurs variables avec la même valeur auront la même case mémoire.
+ **is** et **is not** sont différents de **!=** et **==** pour les variables de types complexes comme les chaines. Deux chaines de mêmes valeurs n'ont pas forcément les mêmes identifiants de case mémoire. Pour les chaines de caractères on utilisera **==** pour vérifier l'égalité des valeurs des variables de types chaine et **!=** pour vérifier la différence entre les valeurs.