*args i **kwargs

Zbieranie dowolnej liczby argumentów pozycyjnych w krotkę i nazwanych w słownik oraz rozpakowywanie kolekcji przy wywołaniu.

Na tej stronie

Przykład

#
Python
def show(*args, **kwargs):
    print(args)
    print(kwargs)

show(7, "Safari", guide="Darwin", modules=12)

def log(level, *messages, **context):
    line = f"[{level}] " + " ".join(str(m) for m in messages)
    if context:
        line += " " + str(context)
    print(line)

log("INFO", "Moduł", 3, "ukończony")
log("WARN", "Brak paliwa", user="ania", fuel=0)
Wynikzapisany wynik, możesz go sprawdzić
(7, 'Safari')
{'guide': 'Darwin', 'modules': 12}
[INFO] Moduł 3 ukończony
[WARN] Brak paliwa {'user': 'ania', 'fuel': 0}

Definicja i zastosowanie

#

Parametr z jedną gwiazdką, zwyczajowo *args, zbiera wszystkie nadmiarowe argumenty pozycyjne w krotkę. Parametr z dwiema gwiazdkami, **kwargs, zbiera nadmiarowe argumenty nazwane w słownik. Dzięki nim funkcja przyjmie dowolną liczbę argumentów, tak jak wbudowane print() czy max().

Liczą się gwiazdki, a nie nazwy, więc równie dobrze możesz napisać *scores albo **options. Kolejność w definicji jest stała: zwykłe parametry, *args, parametry tylko nazwane i na końcu **kwargs. Parametry wpisane po *args albo po samej gwiazdce * można podać wyłącznie po nazwie, a parametry przed znakiem / wyłącznie pozycyjnie.

Gwiazdki działają też w drugą stronę, przy wywołaniu funkcji: *lista rozkłada kolekcję na osobne argumenty pozycyjne, a **slownik na argumenty nazwane. Połączenie obu technik pozwala przekazać wszystkie argumenty dalej bez ich znajomości. Na tym opierają się dekoratory i klasy pochodne, które przekazują parametry do super().__init__().

Składnia

#
Składnia
def funkcja(a, b=0, *args, c, d=1, **kwargs):
    ...

funkcja(*lista, **slownik)

Elementy składni

#
  • *args

    tuple

    Nadmiarowe argumenty pozycyjne zebrane w krotkę. Gdy ich brak, krotka jest pusta.
  • **kwargs

    dict

    Nadmiarowe argumenty nazwane jako słownik {nazwa: wartość}. Gdy ich brak, słownik jest pusty.
  • *

    separator

    Sama gwiazdka w definicji: wszystkie kolejne parametry trzeba podać po nazwie.
  • /

    separator

    Parametry przed ukośnikiem można podać tylko pozycyjnie, bez nazwy.

Więcej przykładów

#
Rozpakowywanie przy wywołaniu
Python
def create_account(name, world, level=1):
    return f"{name}, świat {world}, poziom {level}"

row = ["Ania", 7]
settings = {"world": 2, "level": 5}

print(create_account(*row))
print(create_account("Kuba", **settings))

scores = [72, 95, 64]
print(*scores)
print(max(*scores, 80))
Wynikzapisany wynik, możesz go sprawdzić
Ania, świat 7, poziom 1
Kuba, świat 2, poziom 5
72 95 64
95
Parametry tylko pozycyjne i tylko nazwane
Python
def award(name, /, exp, *, reason="zadanie"):
    return f"{name}: +{exp} EXP ({reason})"

print(award("Ania", 20))
print(award("Kuba", exp=15, reason="seria"))

try:
    award("Ola", 10, "bonus")
except TypeError as error:
    print(error)
Wynikzapisany wynik, możesz go sprawdzić
Ania: +20 EXP (zadanie)
Kuba: +15 EXP (seria)
award() takes 2 positional arguments but 3 were given
Przekazywanie argumentów dalej
Python
class User:
    def __init__(self, name, email=None):
        self.name = name
        self.email = email

class Student(User):
    def __init__(self, *args, world=1, **kwargs):
        super().__init__(*args, **kwargs)
        self.world = world

ola = Student("Ola", email="ola@example.com", world=7)
print(ola.name, ola.email, ola.world)
Wynikzapisany wynik, możesz go sprawdzić
Ola ola@example.com 7

Dobre praktyki

#
  • Nie nadużywaj **kwargs w zwykłych funkcjach. Jawnie wypisane parametry są czytelniejsze, a edytor podpowie je przy wywołaniu i wychwyci literówki.
  • Gwiazdki działają też w literałach: [*a, *b] łączy listy, a {**defaults, **options} scala słowniki. Przy powtórzonym kluczu wygrywa wartość z prawej.
  • Parametry po samej gwiazdce * wymuszają podawanie po nazwie. Przydaje się to przy flagach typu force=True, które bez nazwy byłyby niezrozumiałe.

Powiązane hasła

#

Widzisz błąd albo brakuje przykładu? Napisz do nas.