2.15. Argumentumok

Egy függvényt többféleképpen lehet meghívni, és a paraméterei is többféle formában deklarálhatók. A kombinációk elsőre ijesztőnek tűnnek; a gyakorlatban három-négy minta szinte mindent lefed.

2.15.1. Pozicionális és kulcsszavas argumentumok

A legegyszerűbb hívás pozíció szerint adja át az argumentumokat – az első érték az első paraméterhez kerül, a második a másodikhoz, és így tovább:

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

rect(10, 20, 100, 50)

Ugyanaz a hívás kulcsszó szerint is átadhatja az argumentumokat, mindegyik paramétert explicit módon megnevezve:

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

A kulcsszavas argumentumok sorrendtől függetlenek, és önmagukat dokumentálóvá teszik a hívásokat, cserébe több gépelésért. A pozicionális és kulcsszavas argumentumok keveredhetnek egyetlen hívásban, de minden pozicionálisnak meg kell előznie bármely kulcsszavast:

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

2.15.2. Alapértelmezett értékek

Egy paraméter deklarálhat alapértelmezett értéket, amelyet akkor használ, ha a hívó nem ad meg egyet:

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

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

Az alapértelmezett értékkel rendelkező paramétereknek az alapértelmezett érték nélküliek után kell állniuk a def sorban.

Figyelem

Az alapértelmezett értékek egyszer kerülnek kiértékelésre, amikor a def lefut – nem minden híváskor. Egy módosítható alapértelmezett ([], {}) használata azt eredményezi, hogy ugyanazt az objektumot osztja meg minden olyan hívás, amely az alapértelmezettet veszi át. Helyette használj None értéket őrszemként:

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

2.15.3. Változó hosszúságú: *args és **kwargs

A * előtaggal ellátott paraméter az összes megmaradt pozicionális argumentumot egy tuple típusba gyűjti. A ** előtaggal ellátott paraméter az összes megmaradt kulcsszavas argumentumot egy dict típusba gyűjti. A szokásos nevek az args és a kwargs, de bármely azonosító működik:

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

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

Kimenet:

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

Egy függvénynek ritkán van szüksége mindkettőre. A leggyakoribb felhasználás az argumentumok továbbítása egy burkolóból egy belső hívásba:

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

A hívás helyén lévő tükörkép-szintaxis egy iterálható objektumot pozicionális argumentumokká (*) vagy egy dict típust kulcsszavas argumentumokká (**) csomagol ki:

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. Csak kulcsszavas paraméterek

Egy önállóan álló * a paraméterlistában (névhez nem kapcsolva) minden őt követő paramétert csak kulcsszavassá tesz – a hívónak a nevet kell használnia:

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

Ezt logikai jelzőkhöz és más olyan argumentumokhoz használd, ahol egy puszta érték a hívás helyén nem lenne magától értetődő.