In Python worden standaardargumenten slechts één keer berekend — op het moment van de functie-definitie, en niet bij elke aanroep. Dit betekent dat als een veranderlijk object (zoals een lijst of een woordenboek) als standaardwaarde voor een parameter wordt gebruikt, deze gedeeld zal worden tussen alle aanroepen van de functie waar dat argument niet expliciet is opgegeven.
Voorbeeld:
def append_item(item, items=[]): items.append(item) return items print(append_item(1)) # [1] print(append_item(2)) # [1, 2], terwijl [2] verwacht zou worden
De juiste manier:
def append_item(item, items=None): if items is None: items = [] items.append(item) return items
Nu krijgt elke aanroep zijn eigen lijst.
Vraag: Wat gebeurt er bij herhaalde aanroepen van de functie met een standaardwaarde van een veranderlijk object?
Antwoord: Hetzelfde object wordt bij elke aanroep gewijzigd. Het bovenstaande voorbeeld illustreert dit — de lijst accumulateert alle waarden.
Verhaal In een groot webapplicatie gebruikte men een functie met een standaardparameter van een woordenboek voor het cachen van gegevens. Dit leidde tot het "lekken" van gegevens tussen verschillende gebruikers: iemand wijzigde zijn profiel — en deze wijzigingen werden soms getoond aan een andere gebruiker vanwege de gedeelde staat van het globale woordenboek.
Verhaal In tests gebruikte men een functie met een veranderlijke lijst als standaard voor het verzamelen van statistieken. Gegevens van de ene test "stroomden" over naar de andere, wat leidde tot onverwachte crashes, onmogelijkheid om een bug te reproduceren en complexe debugging.
Verhaal In een microservice voor logaggregatie werd de accumulatie van gebeurtenissen gedaan met behulp van een functie waarvan het standaardargument een lijst was. Logs werden gedupliceerd — tijdelijke accumulatie van oude verzoeken werd zichtbaar voor nieuwe klanten, wat leidde tot uren van onderzoek en dataverlies.