Veranderlijk en Onveranderlijk in Python
Dit artikel legt veranderlijk en onveranderlijk uit in Python.
YouTube Video
Veranderlijk en Onveranderlijk in Python
"Veranderlijk" en "onveranderlijk" verwijzen naar de aanpasbaarheid van een object. Het begrijpen hiervan helpt bij het voorkomen van onverwachte bugs en efficiënt geheugenbeheer.
Wat is Veranderlijk?
Veranderlijke objecten kunnen na aanmaak hun interne status wijzigen.
Belangrijkste Veranderlijke Datatypes
list
dict
set
- Door de gebruiker gedefinieerde klassen (als hun attributen kunnen worden gewijzigd)
Voorbeeld: Een Lijst Wijzigen
1numbers = [1, 2, 3]
2numbers[0] = 100
3print(numbers) # [100, 2, 3]
Een lijst is een veranderlijk object, en de elementen kunnen vrij worden gewijzigd.
Wat is Onveranderlijk?
Onveranderlijke objecten kunnen niet worden gewijzigd nadat ze zijn aangemaakt. Pogingen om ze te wijzigen, resulteren in het aanmaken van een nieuw object.
Belangrijkste Onveranderlijke Datatypes
int
float
str
tuple
bool
frozenset
Voorbeeld: Een String Wijzigen
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"
Strings zijn onveranderlijk, dus je kunt ze niet gedeeltelijk wijzigen.
Vergelijking van Veranderlijk en Onveranderlijk
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
Zoals je in dit voorbeeld kunt zien, worden mutable objecten gedeeld via referentie, waardoor ze andere variabelen kunnen beïnvloeden. Aan de andere kant, onveranderlijke objecten creëren nieuwe instanties bij hertoewijzing, waardoor de oorspronkelijke waarde onaangetast blijft.
Interne werking inspecteren met behulp van id()
In Python kun je de functie id()
gebruiken om het ID van een object te controleren. Het object-ID lijkt op een geheugenadres.
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
Zoals getoond, wordt een nieuw object gemaakt voor onveranderlijke typen, terwijl veranderlijke typen ter plaatse worden aangepast.
Functies en voorzichtigheid met veranderlijke en onveranderlijke objecten
Bij het doorgeven van een veranderlijk object aan een functie, kan de originele data worden aangepast.
Voorbeeld: Een functie die een lijst aanpast
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]
Voorbeeld: Een functie die een getal aanpast
Aan de andere kant resulteert een poging om een onveranderlijk object aan te passen in het creëren van een nieuw object.
1def modify_number(n):
2 n += 10
3
4my_number = 5
5modify_number(my_number)
6print(my_number) # 5 -> unchanged
Praktische overwegingen
Vermijd het gebruik van veranderlijke objecten als standaardargumenten
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]
Omdat standaardargumenten slechts één keer worden geëvalueerd bij het definiëren van de functie, kan het gebruik van veranderlijke objecten tot onverwachte bijwerkingen leiden.
- In het eerste voorbeeld wordt hetzelfde lijstobject elke keer gebruikt wanneer
add_item
wordt aangeroepen. Als je de tweede keeradd_item(2)
aanroept, staat de eerder toegevoegde1
nog steeds in de lijst, wat resulteert in[1, 2]
. - In het verbeterde voorbeeld wordt
None
gebruikt als standaardwaarde, en wordt er een nieuwe lijst aangemaakt binnen de functie als het argumentNone
is. Dit zorgt ervoor dat elke keer dat de functie wordt aangeroepen, er een nieuwe lijst wordt aangemaakt, zodat eerdere resultaten geen invloed hebben op volgende aanroepen.
Vermijd het gebruik van bewerkbare objecten zoals lijsten of dictionaries als standaardargumenten; gebruik in plaats daarvan None
en initialiseer ze binnen de functie. Dit is een fundamentele en belangrijke best practice in Python.
Samenvatting
Om Python's variabelen en datatypes grondig te begrijpen, is het essentieel om de verschillen tussen veranderlijk en onveranderlijk te doorzien. Het begrijpen van deze kenmerken helpt je om onbedoeld gedrag in je code te vermijden en robuustere en leesbaardere programma's te schrijven.
Je kunt het bovenstaande artikel volgen met Visual Studio Code op ons YouTube-kanaal. Bekijk ook het YouTube-kanaal.