Z funkcjami, które ostatnio omawialiśmy, wiąże się inne zagadnienie, a mianowicie argumenty funkcji. Pamiętaj - functions are verbs of programming - i rzeczywiście tak jest, funkcje wykorzystujemy na okrągło, wszędzie, a ich argumenty (zamiennie zwane parametrami) są danymi na jakich pracują. Danymi jakie dostają z zewnątrz.
Argument to bardzo ważna kwestia, bowiem dzięki nim właśnie możemy przekazywać, jak już powiedzieliśmy, funkcji jakieś dane z którymi będzie mogła pracować. Jeśli funkcja to kucharz, to co w jej wnętrzu to przepis, to argumenty będą tutaj składnikami. Do argumentów można mieć różne podejście. Zobaczmy sobie konkretny przykład.

Mamy zadeklarowaną, a nawet wywołaną, funkcje dodawanie, która niechybnie zwróci Nam wynik dodawania trzech cyfr. Możemy je podać jako argumenty, co tutaj jawnie uprawiamy - podajemy kolejno cyfry 2,1 i 3, a funkcja pewnie zwróci nam tutaj cyfrę 6, to jasne. Skąd interpreter wie do jakiego parametru przypisać daną wartość? Ci, którzy uważnie czytali poprzedni artykuł mogą już wiedzieć, znaczenie ma tutaj kolejność. Są to tak zwane argumenty pozycyjne, tak przypominamy sobie podstawy, to jeszcze nie są argumenty kluczowe 😉
Interpreter wie, że jeśli pierwszy parametr w deklaracji funkcji to był parametr a, to pierwszy podany argument w wywołaniu będzie właśnie tym parametrem i do niego należy go przypisać. Z kolei drugi argument w wywołaniu funkcji interpreter przypisze do drugiego parametry, czyli b, i tak dalej. Nic nowego, nic skomplikowanego.
Argumenty kluczowe - wymagane
Natomiast nie samymi argumentami pozycyjnymi się żyje. Do Naszej dyspozycji są też inne sztuczki na argumentach. Zacznijmy od sprostowania i uściślenia. Możemy bowiem podać od razu, przy deklaracji funkcji, wartości parametrów. Będą to wartości domyślne, nie kluczowe jak, zdaje się wspomniałem, we wcześniejszym artykule.

Innymi słowy, powyższy kod ma identyczne działanie do poprzedniego, różnica tkwi w tym, że nie musimy podawać wszystkich argumentów. Argumenty bowiem, które pominiemy, a mają określoną wartość domyślną, 'użyją' sobie tej wartości... domyślnie. Zatem podaliśmy przy wywołaniu tylko jeden argument pozycyjny, a był to argument a. Interpreter dla b i c użył wartości 2 i 3, tak jak określono w definicji. Należy jeszcze napomknąć, że argumenty z wartością domyślną muszą występować po argumentach pozycyjnych w definicji nagłówka funkcji.
Jeśli chodzi o argumenty (a może parametry?) z wartością domyślną, to możemy zrobić takiego fikołka, że podamy wartość dla parametru a, nie podamy wartości dla b, i podamy sobie następnie wartość dla c. Możliwe będzie to, dzięki temu, że mamy pozycje + domyślne wartości. Będziemy tylko musieli określić, że ta Nasza wartość dla c, ma właśnie być dla c, nie dla b. A to możemy zrobić po prostu przypisaniem.

Tutaj po prostu cyfra jeden jest wartością parametru. Wartością b jest natomiast wartość domyślna (bo innej nie podano). Natomiast jako c mamy jasno powiedziane co chcemy mieć pod nazwą c.
W takiej konfiguracji, możemy powiedzieć, że argumenty pozycyjne są tutaj wymagane, bo nie pomijamy ich, a inaczej kluczowe. Natomiast argumenty z wartościami domyślnymi możemy podać. Możemy je pominąć, skoro mają wartości domyślne, to nikt nic nam nie zrobi jak ich nie podamy. Możemy je zatem nazwać argumentami opcjonalnymi.
Zmienna ilość argumentów
Zabawa może się zacząć, gdy piszemy funkcję, która do końca nie będzie świadoma (uwaga na sztuczną inteligencję!) ile argumentów może zostać podanych. Mówiąc inaczej, chcielibyśmy by przyjmowała ona dowolną liczbę argumentów. No i tutaj zaczyna się problem.
Jak wymienić wszystkie parametry, skoro ich liczba jest nieznana. Tutaj z pomocą przychodzi Nam coś co nazywamy args, czyli skrót od arguments. Jest to po prostu zbiór argumentów, reprezentowany przez jedną nazwę. Zobaczmy na przykładzie.

Jak widzimy powyżej, podaliśmy w wywołaniu znacznie więcej argumentów niż wskazywałaby liczba parametrów w definicji. Jest to możliwe, dzięki drugiemu parametrowi, czyli wspomnianym args. Nie bez znaczenia jest też użycie gwiazdki na początku parametru. Gwiazdka pozwala Nam właśnie podać dowolną liczbę argumentów i zgrupować je w tuple. Bez gwiazdki oczywiście byłby to najzwyklejszy parametr pozycyjny.
W praktyce ilość argumentów podawanych przy wywołaniu takiej funkcji może być dowolna. Napisana przez Nas funkcja, przyjmuje obowiązkowo tylko jeden argument, args może być podane, ale nie musi - skoro dowolna liczba argumentów, to też możemy ich nie podawać.
Zobaczmy sobie czy rzeczywiście użycie args powoduje zebranie argumentów w tuple.

Jak zauważamy powyżej, pierwszy z argumentów, zgodnie z oczekiwaniami jest intem. Natomiast drugi, czyli właśnie Nasze args, to nic innego jak tupla - funkcja type dobitnie Nam udowadnia, że mamy do czynienia z obiektem klasy tuple. Możemy zatem pracować z args jak z tuplami 😉
Zmienna ilość argumentów z kluczem - słownik jako args
Może się także zdarzyć sytuacja, że chcielibyśmy każdy z Naszych argumentów w dowolnej ilości, ponazywać. Mamy taką możliwość, tutaj użyjemy czegoś co popularne jest jako kwargs, co jest skrótem od keyword arguments. Podobnie do args zbiera dowolną ilość argumentów, ale przy deklaracji kwargs użyjemy nie jednej gwiazdki, ale dwu. Zobaczmy sobie jak to działa.

Jak widzimy, mamy tutaj do czynienia z ciekawym zachowaniem. Pierwszy podany argument wędruje do pierwszego parametru. Jak mogliśmy się spodziewać. Każda następna cyfra wędruje do drugiego parametru czyli args - które jest tuplą. Natomiast każdy następny argument, będący parą klucz - wartość, wędruje do trzeciego parametru kwargs, który jest słownikiem.
Tak oto mamy pełną dowolność przyjmowania argumentów w tuple, dicty czy pojedyncze wartości i tak też możemy pracować później na tych zbiorach argumentów. Bardzo wygodna i sprytna rzecz, polecam potestować w domu i pochwalić się efektami w komentarzach. Do przeczytania!
