Mutable et Immutable en Python
Cet article explique les notions de mutable et immutable en Python.
YouTube Video
Mutable et Immutable en Python
"Mutable" et "immutable" font référence à la mutabilité d’un objet. Comprendre cela permet d’éviter des bogues inattendus et d’optimiser la gestion de la mémoire.
Qu'est-ce qu'un objet mutable ?
Les objets mutables peuvent voir leur état interne changé après leur création.
Principaux types de données mutables
list
dict
set
- Les classes définies par l'utilisateur (si leurs attributs peuvent être modifiés)
Exemple : Modifier une liste
1numbers = [1, 2, 3]
2numbers[0] = 100
3print(numbers) # [100, 2, 3]
Une liste est un objet mutable et ses éléments peuvent être librement modifiés.
Qu'est-ce qu'un objet immutable ?
Les objets immutables ne peuvent pas être modifiés après leur création. Toute tentative de modification entraîne la création d’un nouvel objet.
Principaux types de données immutables
int
float
str
tuple
bool
frozenset
Exemple : Modifier une chaîne de caractères
1text = "hello"
2# text[0] = "H" # TypeError: 'str' object does not support item assignment
3
4text = "H" + text[1:] # Creates a new string
5print(text) # "Hello"
Les chaînes de caractères sont immutables, donc vous ne pouvez pas les modifier partiellement.
Comparaison entre mutable et immutable
1# Mutable example
2a = [1, 2, 3]
3b = a
4b[0] = 100
5print(a) # [100, 2, 3] -> a is also changed
6
7# Immutable example
8x = 10
9y = x
10y = 20
11print(x) # 10 -> x is unchanged
Comme vous pouvez le voir dans cet exemple, les objets mutables sont partagés par référence, donc ils peuvent affecter d'autres variables. D'autre part, les objets immuables créent de nouvelles instances lors de l'affectation, laissant la valeur originale intacte.
Examiner le comportement interne à l'aide de id()
En Python, vous pouvez utiliser la fonction id()
pour vérifier l'identifiant d'un objet. L'identifiant d'un objet est similaire à une adresse mémoire.
1# Immutable int behavior
2a = 10
3print(id(a)) # e.g., 140715920176592
4a += 1
5print(id(a)) # e.g., 140715920176624 -> ID has changed
6
7# Mutable list behavior
8b = [1, 2, 3]
9print(id(b)) # e.g., 2819127951552
10b.append(4)
11print(id(b)) # Same ID -> only the content has changed
Comme indiqué, un nouvel objet est créé pour les types immuables, tandis que les types mutables sont modifiés sur place.
Fonctions et précautions avec les objets muables et immuables
Lorsqu'un objet muable est passé à une fonction, les données originales peuvent être modifiées.
Exemple : Une fonction qui modifie une liste
1def modify_list(lst):
2 lst.append(100)
3
4my_list = [1, 2, 3]
5modify_list(my_list)
6print(my_list) # [1, 2, 3, 100]
Exemple : Une fonction qui modifie un nombre
En revanche, tenter de modifier un objet immuable entraîne la création d'un nouvel objet.
1def modify_number(n):
2 n += 10
3
4my_number = 5
5modify_number(my_number)
6print(my_number) # 5 -> unchanged
Considérations pratiques
Évitez d'utiliser des objets muables comme arguments par défaut
1# Bad example
2def add_item(item, container=[]):
3 container.append(item)
4 return container
5
6print(add_item(1)) # [1]
7print(add_item(2)) # [1, 2] -> unintended behavior
8
9# Good example
10def add_item(item, container=None):
11 if container is None:
12 container = []
13 container.append(item)
14 return container
15
16print(add_item(1)) # [1]
17print(add_item(2)) # [2]
Étant donné que les arguments par défaut sont évalués une seule fois lors de la définition de la fonction, l'utilisation d'objets muables peut entraîner des effets secondaires inattendus.
- Dans le premier exemple, le même objet liste est utilisé à chaque appel de
add_item
. Lors du second appel àadd_item(2)
, le1
ajouté précédemment est toujours dans la liste, ce qui donne[1, 2]
. - Dans l'exemple amélioré,
None
est utilisé comme valeur par défaut, et une nouvelle liste est créée à l'intérieur de la fonction si l'argument estNone
. Cela garantit qu'une nouvelle liste est créée à chaque appel de la fonction, de sorte que les résultats précédents n'affectent pas les appels suivants.
Évitez d'utiliser des objets mutables comme des listes ou des dictionnaires comme arguments par défaut ; utilisez plutôt None
et initialisez-les à l'intérieur de la fonction. C'est une bonne pratique fondamentale et importante en Python.
Résumé
Pour comprendre en profondeur les variables et les types de données en Python, il est crucial de saisir les différences entre muable et immuable. Comprendre ces caractéristiques vous aide à éviter les comportements indésirables dans votre code et à écrire des programmes plus robustes et lisibles.
Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.