Jak w każdym języku programowania także w Pythonie znajdziemy ciekawe i zastanawiające konstrukcje składni. Na przykład dziwnie wyglądające *args
i **kwargs
w języku Python. Dziś pokażę Ci w jaki sposób poradzić sobie w sytuacji, gdy wywołujemy funkcję, ale nie wiemy ile argumentów do niej zostanie przekazanych. Z taką sytuacją w świecie automatyzacji infrastruktury mamy do czynienia dość często. Rozwiązanie w tym przypadku jest banalnie proste.
Czym są *args i **kwargs?
Sytuacja, w której nie wiemy ile argumentów zostanie przekazanych do funkcji nie jest sporadyczna. W końcu zbieramy dane z wielu źródeł, w różnym stopniu je przetwarzamy, mogą one być zapisane w różnych strukturach danych czy typach zmiennych. Czasem prze wykonaniem funkcji nie wiemy nie tylko ile, ale i jakie wartości do niej będziemy przekazywać. A pisanie oddzielnej metody na każdą przewidywaną przez nas możliwość nie ma po prostu sensu. Stąd powstały specjalne wyrażenia *args
i **kwargs
.
Zacznijmy od tego, że *args
i **kwargs
to nazwy zwyczajowe. Wyrażenie “args” wzięło swoją nazwę od angielskiego słowa “arguments“, zaś “kwargs” od “keyword arguments“. Widzimy zatem pierwszą różnicę wy zastosowaniu tych parametrów . Za pomocą *args
przekazujemy do funkcji dowolną liczbę argumentów pozycyjnych (tuple). Oddzielone są one od siebie przecinkami, mogą być różnego rodzaju , ale co najważniejsze nie odwołujemy się do nich poprzez ich nazwy, ale poprzez indeksy. Nieco inaczej ma się sprawa z **kwargs
, w którym umieszczamy pary klucz-wartość, czyli zmienną słownikową (dictionary). Przetwarzając zapisane w niej dane odwołujemy się do kluczy nie zaś do indeksów.
Jak już wspomniałem *args
i **kwargs
to nazwy zwyczajowe. To nie nazwa zmiennej jest najważniejsza, ale właśnie pojedynczy lub podwójny znak gwiazdki, który je poprzedza, i odróżnia od siebie. Możemy zastosować dowolną nazwę zmiennej, jednak przyjęło się że dla jasnego określenia jakiego typu zmienną przekazujemy używa się tych dwóch nazw te zwyczajowych.
Jak stosujemy te parametry w praktyce?
Korzystanie z *args
i **kwargs
jest bardzo proste. Pamiętajmy, to tak na prawdę jest zmienna, którą traktujemy tak samo jak każdą inną zmienną. Tylko nie znamy jej rozmiaru, czyli ilości elementów, które zawiera, ale to przecież zawsze możemy sprawdzić za pomocą len()
. Zazwyczaj nawet nie musimy tego sprawdzać, gdyż dokonujemy iteracji przez wszystkie elementy.
def funkcja(*args): print("Ilosc zmiennych: ", len(args)) for arg in args: print(arg) funkcja(1, 2, "abc", [1, 2, 3])
Wynikiem wykonania powyższego kodu będzie:
Ilosc zmiennych: 4 1 2 abc [1, 2, 3]
Identycznie postępujemy z **kwargs
pamiętając, że mamy do czynienia ze zmienną słownikową, zatem musimy odczytać zarówno nazwę klucza jak i przypisaną mu wartość:
def funkcja(**kwargs): print("Ilosc zmiennych: ", len(kwargs)) for key, value in kwargs.items(): print("{0} = {1}".format(key, value)) funkcja(jeden=1, dwa=2, trzy="abc", cztery=[1, 2, 3])
W tym przypadku otrzymamy następujący wynik:
Ilosc zmiennych: 4 jeden = 1 dwa = 2 trzy = abc cztery = [1, 2, 3]
Parametry *args
i **kwargs
możemy używać jednocześnie w definicji funkcji. Pamiętajmy jednak, że **kwargs
musi znajdować się na końcu.