2.15. Argument

En funktion kan anropas på flera sätt, och dess parametrar kan deklareras i flera former. Kombinationerna ser skrämmande ut till en början; tre eller fyra mönster täcker nästan allt i praktiken.

2.15.1. Positions- och nyckelordsargument

Det enklaste anropet skickar argument efter position – det första värdet går till den första parametern, det andra till den andra och så vidare:

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

rect(10, 20, 100, 50)

Samma anrop kan skicka argument efter nyckelord, där varje parameter namnges uttryckligen:

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

Nyckelordsargument är oberoende av ordning och gör anrop självdokumenterande till priset av mer skrivande. Positions- och nyckelordsargument kan blandas i ett enda anrop, men varje positionsargument måste komma före alla nyckelordsargument:

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

2.15.2. Standardvärden

En parameter kan deklarera ett standardvärde som används när anroparen inte anger något:

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

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

Parametrar med standardvärden måste komma efter parametrar utan standardvärden i def-raden.

Varning

Standardvärden beräknas en gång, när def körs – inte vid varje anrop. Att använda ett muterbart standardvärde ([], {}) gör att samma objekt delas mellan alla anrop som använder standardvärdet. Använd None som vaktvärde i stället:

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

2.15.3. Variabel längd: *args och **kwargs

En parameter med prefixet * samlar upp eventuella överblivna positionsargument i en tuple. En parameter med prefixet ** samlar upp eventuella överblivna nyckelordsargument i en dict. De konventionella namnen är args och kwargs, men vilken identifierare som helst fungerar:

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

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

Utdata:

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

En funktion behöver sällan båda. Den vanligaste användningen är att vidarebefordra argument från en omslutande funktion till ett inre anrop:

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

Den spegelvända syntaxen på anropsplatsen packar upp en itererbar till positionsargument (*) eller en dict till nyckelordsargument (**):

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. Parametrar endast som nyckelord

Ett ensamt * i parameterlistan (inte fäst vid ett namn) markerar varje parameter som följer som endast nyckelord – anroparen måste använda namnet:

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

Använd detta för booleska flaggor och andra argument där ett naket värde på anropsplatsen inte skulle vara självförklarande.