programowanieProgramista Backend

Jak działa zasada domyślnych argumentów w Pythonie w funkcjach? Dlaczego użycie obiektów zmiennych (np. list) jako wartości domyślnej może prowadzić do nieoczekiwanych wyników? Podaj szczegółowy przykład.

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

W Pythonie argumenty domyślne są obliczane tylko raz — w momencie definiowania funkcji, a nie przy każdym jej wywołaniu. Oznacza to, że jeśli jako wartość domyślną dla parameteru używany jest obiekt zmienny (np. lista lub słownik), będzie on wspólny dla wszystkich wywołań funkcji, gdzie ten argument nie jest jawnie określony.

Przykład:

def append_item(item, items=[]): items.append(item) return items print(append_item(1)) # [1] print(append_item(2)) # [1, 2], a oczekiwano [2]

Prawidłowy sposób:

def append_item(item, items=None): if items is None: items = [] items.append(item) return items

Teraz każde wywołanie otrzymuje swoją listę.

Pytanie z haczykiem.

Pytanie: Co się stanie przy wielokrotnym wywołaniu funkcji z wartością zmiennego obiektu domyślnego?

Odpowiedź: Ten sam obiekt jest modyfikowany za każdym razem. Przykład powyżej ilustruje to — lista gromadzi wszystkie wartości.

Przykłady rzeczywistych błędów z powodu nieznajomości szczegółów tematu.


Historia W dużej aplikacji webowej, podczas kasowania danych, używano funkcji z parametrem - słownikiem jako wartością domyślną. Prowadziło to do tego, że dane między różnymi użytkownikami "przechodziły" do siebie nawzajem: ktoś zmieniał swój profil — a te zmiany czasami pojawiały się u innego użytkownika z powodu wspólnego stanu globalnego słownika.


Historia W testach używano funkcji z zmienną listą jako wartością domyślną do zbierania statystyk. Dane jednego testu "przechodziły" do innego, co prowadziło do nieoczekiwanych awarii, niemożności powtórzenia błędu i trudnej do debugowania sytuacji.


Historia W mikrousłudze do agregacji logów stosowano gromadzenie zdarzeń za pomocą funkcji, gdzie argumentem domyślnym była lista. Logi były duplikowane — tymczasowe gromadzenie z wcześniejszych zapytań trafiało do nowych klientów, co kosztowało godziny dochodzenia i utraty danych.