Mutable e Immutable in Python
Questo articolo spiega il concetto di mutable e immutable in Python.
YouTube Video
Mutable e Immutable in Python
"Mutable" e "immutable" si riferiscono alla mutabilità di un oggetto. Comprenderlo aiuta a evitare bug inattesi e a gestire la memoria in modo efficiente.
Cosa significa Mutable?
Gli oggetti mutable possono cambiare il loro stato interno dopo la creazione.
Principali tipi di dato Mutable
list
dict
set
- Classi definite dall'utente (se i loro attributi possono essere modificati)
Esempio: Modifica di una lista
1numbers = [1, 2, 3]
2numbers[0] = 100
3print(numbers) # [100, 2, 3]
Una lista è un oggetto mutable e i suoi elementi possono essere modificati liberamente.
Cosa significa Immutable?
Gli oggetti immutable non possono essere modificati una volta creati. Tentare di modificarli comporta la creazione di un nuovo oggetto.
Principali tipi di dato Immutable
int
float
str
tuple
bool
frozenset
Esempio: Modifica di una stringa
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"
Le stringhe sono immutable, quindi non possono essere modificate parzialmente.
Confronto tra Mutable e 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
Come si può vedere da questo esempio, gli oggetti mutabili vengono condivisi per riferimento, quindi possono influenzare altre variabili. D'altra parte, gli oggetti immutabili creano nuove istanze durante la riassegnazione, lasciando il valore originale invariato.
Esaminare il Comportamento Interno Usando id()
In Python, puoi usare la funzione id()
per controllare l'ID di un oggetto. L'ID di un oggetto è simile a un indirizzo di memoria.
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
Come mostrato, un nuovo oggetto viene creato per i tipi immutabili, mentre i tipi mutabili vengono modificati in loco.
Funzioni e Attenzione con Oggetti Mutabili e Immutabili
Quando si passa un oggetto mutabile a una funzione, i dati originali possono essere modificati.
Esempio: Una Funzione che Modifica una Lista
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]
Esempio: Una Funzione che Modifica un Numero
D'altra parte, tentare di modificare un oggetto immutabile comporta la creazione di un nuovo oggetto.
1def modify_number(n):
2 n += 10
3
4my_number = 5
5modify_number(my_number)
6print(my_number) # 5 -> unchanged
Considerazioni Pratiche
Evita di Usare Oggetti Mutabili come Argomenti di Default
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]
Poiché gli argomenti di default vengono valutati solo una volta alla definizione della funzione, l'uso di oggetti mutabili può portare a effetti collaterali inattesi.
- Nel primo esempio, lo stesso oggetto lista viene utilizzato ogni volta che si chiama
add_item
. Quando si chiamaadd_item(2)
la seconda volta, l'elemento1
aggiunto in precedenza è ancora presente nella lista, risultando in[1, 2]
. - Nell'esempio migliorato,
None
viene usato come valore predefinito e una nuova lista viene creata all'interno della funzione se l'argomento èNone
. Questo garantisce che una nuova lista venga creata ogni volta che la funzione viene chiamata, così i risultati precedenti non influenzano le chiamate successive.
Evita di usare oggetti mutabili come liste o dizionari come argomenti predefiniti; usa invece None
e inizializzali all'interno della funzione. Questa è una buona pratica fondamentale e importante in Python.
Riepilogo
Per comprendere a fondo le variabili e i tipi di dati di Python, è fondamentale afferrare le differenze tra mutabile e immutabile. Comprendere queste caratteristiche ti aiuta ad evitare comportamenti indesiderati nel tuo codice e a scrivere programmi più robusti e leggibili.
Puoi seguire l'articolo sopra utilizzando Visual Studio Code sul nostro canale YouTube. Controlla anche il nostro canale YouTube.