ProgrammationDéveloppeur Python Backend

Qu'est-ce que la mutabilité (mutable/immutable) des objets en Python ? Comment cela influence-t-il le fonctionnement des fonctions et le passage des paramètres ? Donnez des exemples d'erreurs typiques.

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Mutabilité détermine s'il est possible de modifier un objet sans changer son identifiant (adresse en mémoire) :

  • Objets mutables (par exemple, list, dict, set) peuvent être modifiés : ajouter des éléments, changer ou supprimer.
  • Objets immuables (par exemple, int, str, tuple, frozenset) ne peuvent pas être modifiés après leur création — toutes les "modifications" créent un nouvel objet.

Impact sur les fonctions :

  • Lorsque vous passez un objet mutable à une fonction — elle peut le modifier.
  • Avec des objets immuables, aucune modification ne se produira, même si vous "remplacez" leur valeur à l'intérieur de la fonction.

Exemple :

def f(lst): lst.append(42) data = [] f(data) print(data) # [42] def f2(x): x += 1 n = 1 f2(n) print(n) # 1

Question piège.

"Que renverra le code suivant ?"

def foo(bar=[]): bar.append(1) return bar print(foo()) print(foo())

Réponse : Renvoie :

[1]
[1, 1]

Parce que les arguments de fonction sont initialisés une seule fois lors de la définition, et non à chaque appel. Les listes (et autres objets mutables) dans les arguments de fonction — piège populaire.

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet.


Histoire

Dans une API REST, une liste était renvoyée par une fonction avec un paramètre par défaut :

def get_default_items(items=[]): items.append('x') return items

Après plusieurs appels, on a découvert que la liste grossissait, alors qu'on s'attendait à n'obtenir qu'un seul élément.


Histoire

Dans une fonction, on prévoyait de "remplacer" une chaîne :

def replace_word(word): word.replace('a', 'b') word = 'data' replace_word(word) print(word) # On s'attendait à 'dbtb', on obtient 'data'

Les méthodes str ne modifient pas la chaîne d'origine, mais retournent une nouvelle, cependant, la valeur du résultat retourné a été ignorée.


Histoire

En travaillant avec des structures imbriquées :

original = [[1, 2], [3, 4]] copy = original[:] copy[0][0] = -1 print(original) # [[-1, 2], [3, 4]]

Une copie superficielle a été utilisée, pensant que seule la copie avait été modifiée, mais les objets imbriqués sont restés communs.