programowanieProgramista Python

Wyjaśnij, jak działają argumenty *args i **kwargs w funkcjach Pythona. Do czego są używane, jakie mogą stanowić zagrożenie przy niewłaściwym zastosowaniu i jak je poprawnie łączyć z argumentami zwykłymi i nazwanymi?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

*args — zbiera dowolną liczbę pozycyjnych argumentów w krotce.

**kwargs — zbiera dowolną liczbę argumentów nazwanych (klucz=wartość) w słowniku.

Umożliwia to pisanie funkcji z elastycznym interfejsem:

def my_func(a, b, *args, **kwargs): print(a, b) print(args) print(kwargs) my_func(1, 2, 3, 4, x=10, y=20) # 1 2 # (3, 4) # {'x': 10, 'y': 20}

Zasady:

  • Argumenty zwykłe muszą być na pierwszym miejscu, potem *args, po nich argumenty nazwane z wartościami domyślnymi, a na końcu **kwargs — ściśle w takiej kolejności przy deklaracji funkcji.
  • Można "rozpakować" sekwencje przez *, a słowniki przez ** podczas wywoływania funkcji.
  • Nie można powtarzać tych samych parametrów — pojawi się błąd TypeError.

Pytanie podchwytliwe

Czy można zamienić miejscami *args i argumenty nazwane z wartością domyślną, na przykład:

def foo(a, *args, x=10, **kwargs): pass

*czy wartości domyślne muszą zawsze być po args?

Odpowiedź:

W Pythonie 3 można! Oto jak (nie działało w Pythonie 2):

def foo(a, *args, x=10): pass

Parametry po *args ("argumenty tylko nazwane") mogą mieć wartości domyślne lub być obowiązkowe — można je podawać tylko według nazwy.

Przykłady rzeczywistych błędów wynikających z braku znajomości tematu


Historia

Przekazywanie niewłaściwych argumentów przez *args/**kwargs

W usługach REST API automatyzacja marszalu danych opierała się na **kwargs. Dodatni parametr nie został zauważony — funkcja przyjęła nieoczekiwaną wartość w kwargs, co prowadziło do utraty logiki kontrolnej i trudnych do debugowania błędów.


Historia

Duplikowanie argumentów nazwanych

Podczas wywołania funkcji programista przypadkowo wskazał parametr i jawnie, i przez **kwargs, na przykład: my_func(a=1, **{"a": 2}). W efekcie — TypeError i awaria usługi.


Historia

Zapomniano o pozycyjnych lub tylko nazwanych argumentach

Podczas pisania dekoratora niewłaściwe przekazanie parametrów (niedostosowanie kolejności i struktury) prowadziło do tego, że oryginalna funkcja otrzymywała niewłaściwą liczbę argumentów, co skutkowało na produkcji błędami wywołania TypeError.