W Pythonie można deklarować parametry funkcji czterech rodzajów: pozycyjne, nazwane (keyword), tylko pozycyjne (positional-only) i tylko nazwane (keyword-only). Ich różnice wpływają na sposób przekazywania wartości podczas wywoływania funkcji.
/ (Python 3.8+), nie można wskazać ich po nazwie.*, można je wskazać tylko po kluczu.# Przykład wszystkich typów def func(a, b, /, c, *, d, e): print(a, b, c, d, e) func(1, 2, 3, d=4, e=5) # OK # func(a=1, b=2, 3, d=4, e=5) # Błąd: a, b - tylko pozycyjne
SyntaxError lub TypeError.*args zbiera dodatkowe pozycyjne; **kwargs — nazwane.Czym różnią się deklaracje funkcji:
def f(a, b, c): ... def f(a, b, c=1): ... def f(a, b=1, c=2): ... def f(a=1, b=2, c=3): ...
i czy prawdą jest, że wszystkie te funkcje można wywoływać zarówno z argumentami pozycyjnymi, jak i kluczowymi?
def f(a, b, c): nie można wywołać wyłącznie z argumentami kluczowymi, ponieważ wszystkie można przekazać zarówno po pozycji, jak i po kluczu, ale wszystkie argumenty są obowiązkowe.def f(a, b, /, c):, to a i b można przekazać tylko pozycyjnie.def f(a, b, c=10): print(a, b, c) f(1, 2) # OK, c=10 domyślnie f(a=1, b=2, c=3) # OK # A oto: def f(a, b, /, c=10): ... f(1, 2) # OK f(a=1, b=2, c=3) # Błąd! a i b tylko pozycyjnie
Historia
Programista zrealizował funkcję, która zgodnie z umową powinna przyjmować parametry wyłącznie po nazwie: logowanie z wieloma parametrami, część z nich opcjonalna. Jednak zapomniano zadeklarować * — i użytkownicy przypadkowo przekazywali parametry w różnej kolejności pozycyjnej, co prowadziło do niewłaściwego logowania i błędów, które były trudne do zlokalizowania.
Historia
W projekcie z REST API z powodu niejawnej umowy o kolejności argumentów (używano *args i nie ograniczano parametrów po nazwie) przestały działać zapytania po wprowadzeniu nowej wersji klienta — ponieważ args się przesunęły. Naprawiono to poprzez wprowadzenie jawnych * i wskazanie tylko nazwanych argumentów.
Historia
W dużym projekcie korporacyjnym funkcję rozszerzono o nowe parametry z wartościami domyślnymi, ale z powodu błędnego wywołania z wartościami pozycyjnymi stary kod zaczął podstawiać wartości do innych parametrów, co spowodowało nieprawidłowe przetwarzanie danych. Okazało się, że parametry powinny być tylko nazwane.