Veranderlijk en Onveranderlijk in Python

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 keer add_item(2) aanroept, staat de eerder toegevoegde 1 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 argument None 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.

YouTube Video