2.15. Argumentos

Uma função pode ser chamada de várias formas, e os seus parâmetros podem ser declarados de várias maneiras. As combinações podem parecer intimidantes ao início; três ou quatro padrões cobrem quase tudo na prática.

2.15.1. Argumentos posicionais e por palavra-chave

A chamada mais simples passa argumentos por posição – o primeiro valor vai para o primeiro parâmetro, o segundo para o segundo, e assim por diante:

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

rect(10, 20, 100, 50)

A mesma chamada pode passar argumentos por palavra-chave, nomeando cada parâmetro explicitamente:

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

Os argumentos por palavra-chave são independentes da ordem e tornam as chamadas autodocumentadas, ao custo de escrever mais. Argumentos posicionais e por palavra-chave podem misturar-se numa única chamada, mas todos os posicionais têm de aparecer antes de qualquer argumento por palavra-chave:

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

2.15.2. Valores predefinidos

Um parâmetro pode declarar um valor predefinido a utilizar quando o chamador não fornece nenhum:

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

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

Os parâmetros com valores predefinidos têm de vir depois dos parâmetros sem valores predefinidos na linha def.

Aviso

Os valores predefinidos são avaliados uma vez, quando o def é executado – não em cada chamada. Usar um valor predefinido mutável ([], {}) faz com que o mesmo objeto seja partilhado por todas as chamadas que usem o predefinido. Use None como sentinela:

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

2.15.3. Comprimento variável: *args e **kwargs

Um parâmetro prefixado com * recolhe quaisquer argumentos posicionais restantes num tuple. Um parâmetro prefixado com ** recolhe quaisquer argumentos por palavra-chave restantes num dict. Os nomes convencionais são args e kwargs, mas qualquer identificador funciona:

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

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

Resultado:

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

Uma função raramente necessita de ambos. O uso mais comum é reencaminhar argumentos de um invólucro para uma chamada interna:

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

A sintaxe espelho no sítio de chamada desempacota um iterável em argumentos posicionais (*) ou um dict em argumentos por palavra-chave (**):

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. Parâmetros apenas por palavra-chave

Um * isolado na lista de parâmetros (sem estar ligado a um nome) marca todos os parâmetros que se seguem como apenas por palavra-chave – o chamador tem de usar o nome:

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

Use isto para flags booleanas e outros argumentos onde um valor simples no sítio de chamada não seria autoexplicativo.