2.15. Argumenti

Funkcija se može pozvati na nekoliko načina, a njezini se parametri mogu deklarirati u nekoliko oblika. Kombinacije na prvi pogled djeluju zastrašujuće; u praksi tri ili četiri obrasca pokrivaju gotovo sve.

2.15.1. Pozicijski i imenovani argumenti

Najjednostavniji poziv prosljeđuje argumente po poziciji – prva vrijednost ide prvom parametru, druga drugom i tako dalje:

def rect(x, y, w, h):
    return (x, y, w, h)

rect(10, 20, 100, 50)

Isti poziv može proslijediti argumente po ključnoj riječi, eksplicitno imenujući svaki parametar:

rect(x=10, y=20, w=100, h=50)

Imenovani argumenti neovisni su o redoslijedu i čine pozive samodokumentirajućima po cijenu više tipkanja. Pozicijski i imenovani argumenti mogu se miješati u jednom pozivu, ali svaki pozicijski mora doći prije bilo kojeg imenovanog:

rect(10, 20, w=100, h=50)         # OK
rect(x=10, 20, 100, 50)           # SyntaxError

2.15.2. Zadane vrijednosti

Parametar može deklarirati zadanu vrijednost koja se koristi kada ju pozivatelj ne navede:

def greet(name, greeting="hello"):
    print(greeting, name)

greet("Alice")                    # hello Alice
greet("Alice", "hi")              # hi Alice
greet("Alice", greeting="hey")    # hey Alice

Parametri sa zadanim vrijednostima moraju doći iza parametara bez zadanih vrijednosti u retku def.

Upozorenje

Zadane vrijednosti vrednuju se jednom, kada se def izvrši – ne pri svakom pozivu. Korištenje promjenjive zadane vrijednosti ([], {}) uzrokuje da se isti objekt dijeli kroz svaki poziv koji preuzme zadanu vrijednost. Umjesto toga koristite None kao indikator (sentinel):

def append_to(item, target=None):
    if target is None:
        target = []
    target.append(item)
    return target

2.15.3. Promjenjiva duljina: *args i **kwargs

Parametar s prefiksom * skuplja sve preostale pozicijske argumente u tuple. Parametar s prefiksom ** skuplja sve preostale imenovane argumente u dict. Uobičajeni nazivi su args i kwargs, ali bilo koji identifikator funkcionira:

def report(label, *values, **options):
    print(label, values, options)

report("temps", 21, 22, 23, unit="C", precision=1)

Ispis:

temps (21, 22, 23) {'unit': 'C', 'precision': 1}

Funkciji rijetko trebaju oba. Najčešća uporaba je prosljeđivanje argumenata iz omotača (wrapper) u unutarnji poziv:

def log_and_call(func, *args, **kwargs):
    print("calling", func.__name__)
    return func(*args, **kwargs)

Zrcalna sintaksa na mjestu poziva raspakirava iterabilni objekt u pozicijske argumente (*) ili dict u imenovane argumente (**):

point = (10, 20, 100, 50)
rect(*point)                      # same as rect(10, 20, 100, 50)

kwargs = {"x": 10, "y": 20, "w": 100, "h": 50}
rect(**kwargs)                    # same as rect(x=10, y=20, ...)

2.15.4. Isključivo imenovani parametri

Samostalni * u popisu parametara (koji nije pridružen imenu) označava svaki parametar koji slijedi kao isključivo imenovan – pozivatelj mora koristiti ime:

def crop(buffer, *, x, y, w, h):
    ...

crop(buffer, x=0, y=0, w=100, h=100)   # OK
crop(buffer, 0, 0, 100, 100)           # TypeError

Koristite ovo za logičke zastavice i druge argumente kod kojih gola vrijednost na mjestu poziva ne bi bila samorazumljiva.