2.15. Argumentos¶
Uma função pode ser chamada de várias maneiras, e seus parâmetros podem ser declarados de várias formas. As combinações parecem intimidadoras no início; na prática, três ou quatro padrões cobrem quase tudo.
2.15.1. Argumentos posicionais e nomeados¶
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 nome, nomeando cada parâmetro explicitamente:
rect(x=10, y=20, w=100, h=50)
Argumentos nomeados independem da ordem e tornam as chamadas autodocumentadas ao custo de digitar mais. Argumentos posicionais e nomeados podem ser misturados em uma única chamada, mas todo posicional deve aparecer antes de qualquer nomeado:
rect(10, 20, w=100, h=50) # OK
rect(x=10, 20, 100, 50) # SyntaxError
2.15.2. Valores padrão¶
Um parâmetro pode declarar um valor padrão a ser usado quando quem chama não fornece um:
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 padrão devem vir depois dos parâmetros sem valores padrão na linha def.
Aviso
Os valores padrão são avaliados uma única vez, quando o def é executado – não a cada chamada. Usar um padrão mutável ([], {}) faz com que o mesmo objeto seja compartilhado por todas as chamadas que usam o padrão. Em vez disso, use None como sentinela:
def append_to(item, target=None):
if target is None:
target = []
target.append(item)
return target
2.15.3. Tamanho variável: *args e **kwargs¶
Um parâmetro prefixado com * reúne quaisquer argumentos posicionais restantes em uma tuple. Um parâmetro prefixado com ** reúne quaisquer argumentos nomeados restantes em um 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)
Saída:
temps (21, 22, 23) {'unit': 'C', 'precision': 1}
Raramente uma função precisa de ambos. O uso mais comum é encaminhar argumentos de um wrapper para uma chamada interna:
def log_and_call(func, *args, **kwargs):
print("calling", func.__name__)
return func(*args, **kwargs)
A sintaxe espelhada no local da chamada desempacota um iterável em argumentos posicionais (*) ou um dict em argumentos nomeados (**):
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 somente nomeados¶
Um * isolado na lista de parâmetros (não anexado a um nome) marca todos os parâmetros que o seguem como somente nomeados – quem chama deve 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 isso para flags booleanas e outros argumentos em que um valor sem nome no local da chamada não seria autoexplicativo.