Menu

*args i **kwargs w Pythonie: elastyczne argumenty pozycyjne i nazwane

Co oznaczają *args i **kwargs, kiedy ich używać i jak czysto przekazywać argumenty między funkcjami.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Gdy nie wiesz, ile będzie argumentów

Większość funkcji przyjmuje stałą liczbę parametrów. Czasem jednak potrzebujesz czegoś bardziej elastycznego: loggera, który przyjmuje dowolną liczbę komunikatów, funkcji opakowującej, która przekazuje wszystko, co dostała, do innej funkcji, albo funkcji rysującej wykresy, która przyjmuje konfigurację, nie wiedząc dokładnie, jakich opcji użyje wywołujący.

Python rozwiązuje to dwoma specjalnymi znacznikami na liście parametrów: *args i **kwargs.

*args zbiera argumenty pozycyjne

Pojedyncza gwiazdka oznacza "spakuj wszystkie dodatkowe argumenty pozycyjne w krotkę":

Wewnątrz funkcji args to zwykła krotka. Możesz iterować po niej pętlą, odwoływać się do elementów przez indeks, przekazać ją do len() albo ją wycinać.

*args zwykle występuje obok nazwanych parametrów:

first przechwytuje pierwszy argument, a *rest pakuje wszystko, co po nim, w krotkę.

**kwargs zbiera argumenty nazwane

Dwie gwiazdki robią to samo dla argumentów nazwanych, pakując je w słownik:

Wewnątrz describe zmienna kwargs to zwykły słownik. Kluczami są nazwy argumentów jako napisy.

Używanie obu naraz

Możesz użyć obu w tej samej funkcji. Konwencja to *args przed **kwargs:

Pełna kolejność parametrów, od pierwszego do ostatniego, wygląda tak:

  1. Zwykłe parametry pozycyjne (wymagane lub z wartościami domyślnymi).
  2. *args.
  3. Parametry tylko nazwane (wszystko po *args trzeba przekazać przez nazwę).
  4. **kwargs.

title przechwytuje pierwszy argument pozycyjny. Pozostałe pozycyjne trafiają do tags. draft trzeba przekazać przez nazwę (występuje po *tags). Wszystkie inne argumenty nazwane lądują w metadata.

Rozpakowywanie przez * i ** przy wywołaniu

Gwiazdki działają też w drugą stronę: rozkładają sekwencję albo słownik na argumenty wywołania:

To niezwykle przydatne przy przekazywaniu argumentów dalej:

wrapped nie musi wiedzieć, jakich argumentów oczekuje log. Po prostu zbiera wszystko i przekazuje dalej. Ten wzorzec pojawia się bardzo często w dekoratorach (temat dla bardziej zaawansowanych) i funkcjach opakowujących.

Kiedy *args i **kwargs to zły wybór

Łatwo dać się ponieść i używać ich wszędzie. Dwa ostrzeżenia:

Ukrywają, czego funkcja oczekuje

Jeśli każda funkcja w twoim kodzie wygląda jak def f(*args, **kwargs), kod wywołujący nie ma pojęcia, jakie argumenty są poprawne. Używaj nazwanych parametrów, kiedy tylko możesz, a *args/**kwargs zostaw dla naprawdę zmiennej liczby wejść albo czystego przekazywania dalej.

Komunikaty o błędach stają się niejasne

Literówka w nazwie argumentu zamienia się w cichy None albo w KeyError głęboko w funkcji, zamiast natychmiastowego "unexpected keyword argument" w miejscu wywołania. Nazwane parametry dają dużo lepszą informację zwrotną.

Zasada: domyślnie wybieraj nazwane parametry, a po *args/**kwargs sięgaj tylko wtedy, gdy funkcja jest naprawdę elastyczna albo przekazuje argumenty do innego obiektu wywoływalnego.

Mały praktyczny przykład

Pomocnik w stylu funkcji do wykresów, który opakowuje funkcję z zewnętrznej biblioteki kilkoma wartościami domyślnymi:

*values pozwala wywołującym przekazać dowolną liczbę elementów, a **style przyjmuje dodatkową konfigurację bez wymogu, by każda opcja była nazwanym parametrem. Jest to elastyczne, a jednocześnie czytelne, bo wewnętrzna logika mówi dokładnie, jakie klucze odczytuje ze style.

Podsumowanie

  • *args pakuje dodatkowe argumenty pozycyjne w krotkę.
  • **kwargs pakuje dodatkowe argumenty nazwane w słownik.
  • Przy wywołaniu *seq i **dict rozpakowują w przeciwną stronę.
  • Parametry muszą występować w kolejności: zwykłe → *args → tylko nazwane → **kwargs.
  • Nie nadużywaj ich: nazwane parametry są czytelniejsze, gdy możesz ich użyć.

Dalej: lambda, sposób na pisanie małych, jednorazowych funkcji w jednej linii.

Najczęściej zadawane pytania

Czym jest *args w Pythonie?

*args zbiera wszystkie dodatkowe argumenty pozycyjne w krotkę. def f(*args): pozwala wywołać f(1, 2, 3) i otrzymać args jako (1, 2, 3). Nazwa args to konwencja: możesz ją nazwać dowolnie, ale wszyscy używają *args.

Czym jest **kwargs w Pythonie?

**kwargs zbiera wszystkie dodatkowe argumenty nazwane w słownik. def f(**kwargs): pozwala wywołać f(name='Ada', age=30) i otrzymać kwargs jako {'name': 'Ada', 'age': 30}. Razem *args i **kwargs pozwalają funkcji przyjąć dowolną kombinację argumentów.

Czy muszę je nazywać args i kwargs?

Nie, liczą się gwiazdki, a nie nazwy. *values i **options działają identycznie. Jednak args i kwargs to niemal powszechna konwencja w kodzie Pythona, więc trzymaj się jej, chyba że masz konkretny powód, by wybrać coś bardziej opisowego.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ