2.15. Argumenty

Funkci lze volat několika způsoby a její parametry lze deklarovat v několika podobách. Kombinace na první pohled působí zastrašujícím dojmem; tři nebo čtyři vzory v praxi pokryjí téměř vše.

2.15.1. Poziční a klíčové argumenty

Nejjednodušší volání předává argumenty podle pozice – první hodnota jde do prvního parametru, druhá do druhého a tak dále:

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

rect(10, 20, 100, 50)

Totéž volání může předat argumenty pomocí klíčového slova a každý parametr explicitně pojmenovat:

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

Klíčové argumenty jsou nezávislé na pořadí a činí volání samodokumentující za cenu více psaní. Poziční a klíčové argumenty lze v jednom volání kombinovat, ale každý poziční musí být uveden před jakýmkoli klíčovým:

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

2.15.2. Výchozí hodnoty

Parametr může deklarovat výchozí hodnotu, která se použije, když ji volající neposkytne:

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

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

Parametry s výchozími hodnotami musí v řádku def následovat za parametry bez výchozích hodnot.

Varování

Výchozí hodnoty se vyhodnotí jednou, když se def spustí – nikoli při každém volání. Použití měnitelné výchozí hodnoty ([], {}) způsobí, že stejný objekt je sdílen napříč každým voláním, které výchozí hodnotu přijme. Místo toho použijte None jako strážní hodnotu:

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

2.15.3. Proměnná délka: *args a **kwargs

Parametr s prefixem * shromáždí všechny zbývající poziční argumenty do tuple. Parametr s prefixem ** shromáždí všechny zbývající klíčové argumenty do dict. Konvenční názvy jsou args a kwargs, ale funguje jakýkoli identifikátor:

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

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

Výstup:

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

Funkce zřídka potřebuje obojí. Nejběžnějším použitím je předávání argumentů z obalu do vnitřního volání:

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

Zrcadlová syntaxe na místě volání rozbalí iterovatelný objekt do pozičních argumentů (*) nebo dict do klíčových argumentů (**):

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. Parametry pouze pro klíčové slovo

Samostatná * v seznamu parametrů (nepřipojená k názvu) označuje každý následující parametr jako pouze pro klíčové slovo – volající musí použít název:

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

Použijte to pro logické příznaky a další argumenty, kde by holá hodnota na místě volání nebyla srozumitelná sama o sobě.