W Pythonie, funkcje są blokami kodu, które wykonują określone zadania. Można przekazywać do nich różne dane, nazywane argumentami. Istnieją specjalne symbole, takie jak gwiazdka (*) i podwójna gwiazdka (**), które pozwalają na przekazywanie argumentów w bardziej elastyczny sposób. Zrozumienie ich działania jest kluczowe do pisania bardziej uniwersalnych i czytelnych funkcji.
Użycie pojedynczej gwiazdki (*)
Pojedyncza gwiazdka (*) przed parametrem w definicji funkcji służy do zbierania nieokreślonej liczby argumentów pozycyjnych. Te argumenty są przekazywane do funkcji jako krotka (tuple). To oznacza, że funkcja może przyjąć dowolną liczbę argumentów, a wszystkie one zostaną zgrupowane w jedną zmienną.
Spójrzmy na przykład. Zdefiniujmy funkcję suma, która oblicza sumę dowolnej liczby podanych liczb. Użyjemy *args, aby zebrać wszystkie argumenty pozycyjne.
def suma(*args):
wynik = 0
for liczba in args:
wynik += liczba
return wynik
print(suma(1, 2, 3)) # Wynik: 6
print(suma(1, 2, 3, 4, 5)) # Wynik: 15
W tym przykładzie, *args zbiera wszystkie argumenty (1, 2, 3) lub (1, 2, 3, 4, 5) do krotki. Następnie funkcja iteruje po tej krotce i sumuje elementy.
Praktyczne zastosowania *args
*args jest przydatny w sytuacjach, gdy nie wiadomo z góry, ile argumentów funkcja powinna przyjąć. Może to być funkcja logująca, która przyjmuje różne komunikaty do wyświetlenia, lub funkcja konfigurująca parametry urządzenia.
Rozważmy funkcję loguj, która wyświetla komunikaty z prefiksem daty. Możemy przekazywać dowolną liczbę komunikatów.
def loguj(*komunikaty):
import datetime
data = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
for komunikat in komunikaty:
print(f"{data} - {komunikat}")
loguj("Uruchomienie programu", "Pobieranie danych", "Zakończenie sukcesem")
Użycie podwójnej gwiazdki (**)
Podwójna gwiazdka (**) przed parametrem w definicji funkcji służy do zbierania nieokreślonej liczby argumentów nazwanych (keyword arguments). Te argumenty są przekazywane do funkcji jako słownik (dictionary). Oznacza to, że funkcja może przyjąć dowolną liczbę argumentów w postaci klucz=wartość, a wszystkie one zostaną zgrupowane w jeden słownik.
Przykład: Zdefiniujmy funkcję osoba, która wyświetla informacje o osobie, przyjmując argumenty nazwane jak imię, nazwisko i wiek.
def osoba(**kwargs):
for klucz, wartosc in kwargs.items():
print(f"{klucz}: {wartosc}")
osoba(imie="Jan", nazwisko="Kowalski", wiek=30)
W tym przykładzie, **kwargs zbiera argumenty nazwane (imie="Jan", nazwisko="Kowalski", wiek=30) do słownika. Następnie funkcja iteruje po tym słowniku i wyświetla pary klucz-wartość.
Praktyczne zastosowania **kwargs
**kwargs jest użyteczne, gdy funkcja musi przyjąć opcjonalne parametry konfiguracyjne. Pozwala to na przekazywanie tylko tych parametrów, które są potrzebne, bez konieczności definiowania ich wszystkich w definicji funkcji.
Rozważmy funkcję rysuj_okrag, która rysuje okrąg na ekranie. Może przyjmować opcjonalne parametry jak kolor, grubość linii i styl linii.
def rysuj_okrag(x, y, promien, **kwargs):
kolor = kwargs.get("kolor", "czarny") # Domyślny kolor: czarny
grubosc = kwargs.get("grubosc", 1) # Domyślna grubość: 1
styl = kwargs.get("styl", "ciągła") # Domyślny styl: ciągła
print(f"Rysuję okrąg o środku ({x}, {y}), promieniu {promien}, kolorze {kolor}, grubości {grubosc} i stylu {styl}")
rysuj_okrag(100, 100, 50, kolor="czerwony", grubosc=3)
rysuj_okrag(200, 200, 75) # Używa domyślnych wartości
Łączenie *args i **kwargs
Można łączyć *args i **kwargs w jednej funkcji. W takim przypadku, funkcja może przyjmować zarówno argumenty pozycyjne, jak i nazwane. Ważna jest kolejność definicji parametrów: najpierw argumenty pozycyjne, potem *args, następnie argumenty nazwane, a na końcu **kwargs.
Przykład:
def funkcja(arg1, arg2, *args, kwarg1="domyslna", **kwargs):
print(f"arg1: {arg1}")
print(f"arg2: {arg2}")
print(f"args: {args}")
print(f"kwarg1: {kwarg1}")
print(f"kwargs: {kwargs}")
funkcja(1, 2, 3, 4, kwarg1="nowa_wartosc", klucz1="wartosc1", klucz2="wartosc2")
W tym przykładzie: arg1 i arg2 to argumenty pozycyjne, *args zbiera dodatkowe argumenty pozycyjne (3, 4), kwarg1 to argument nazwany z wartością domyślną, a **kwargs zbiera dodatkowe argumenty nazwane (klucz1="wartosc1", klucz2="wartosc2").
Użycie *args i **kwargs pozwala na tworzenie bardzo elastycznych funkcji, które mogą dostosowywać się do różnych sytuacji. Pamiętaj o kolejności argumentów, aby uniknąć błędów.

