Para conheceres os fundamentos dos argumentos de funções, consulta o conceito de funções.
Os nomes dos parâmetros, tal como os nomes das variáveis, têm de começar por uma letra ou um underscore e podem conter letras, underscores ou números. Os nomes dos parâmetros não devem conter espaços nem pontuação.
Os argumentos posicionais são valores passados a uma função na mesma ordem dos parâmetros a que ficam associados. Opcionalmente, os argumentos posicionais podem ser passados usando o nome do parâmetro:
def concat(greeting, name):
return f"{greeting}{name}"
# Passing data to the function by position.
print(concat("Hello, ", "Lilly"))
#-> Hello, Lilly
# Passing data to the function using the parameter name.
print(concat(name="Glenn", greeting="Hello, "))
#-> Hello, Glenn
A primeira chamada a concat passa os argumentos por posição.
A segunda chamada a concat passa os argumentos por nome, o que permite alterar as suas posições.
Repara que os argumentos posicionais não podem vir depois de argumentos passados por nome (_também chamados argumentos nomeados. Não devem ser confundidos com parâmetros var-posicionais nem com **kwargs**).
Este conjunto de argumentos:
print(concat(greeting="Hello, ", "Gregor"))
Dá origem a este erro:
SyntaxError: positional argument follows keyword argument
Para exigir argumentos apenas posicionais nas chamadas a funções, podes usar o operador / na lista de parâmetros:
# Parameters showing a position-only operator.
def concat(greeting, name, /):
return f"{greeting}{name}"
print(concat("Hello, ", "Ginnie"))
#-> Hello, Ginnie
# Call to the function using keyword arguments.
print(concat(name="Franklin", greeting="Hello, "))
Traceback (most recent call last):
print(concat(name="Franklin", greeting="Hello, "))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting, name'
Os argumentos nomeados usam o nome do parâmetro ao chamar uma função. Podem, opcionalmente, ser indicados por posição:
def concat(greeting, name):
return f"{greeting}{name}"
# Function call using parameter names as argument keywords.
print(concat(name="Eliza", greeting="Hello, "))
#-> Hello, Eliza
# Function call with positional data as arguments.
print(concat("Hello, ", "Tim"))
#-> Hello, Tim
Para exigir argumentos apenas nomeados nas chamadas a funções, podes usar o operador * na lista de parâmetros:
# Function definition requiring keyword-only arguments.
def concat(*, greeting, name):
return f"{greeting}{name}"
# Keyword arguments can be in an arbitrary order.
print(concat(name="Kimmie", greeting="Hello, "))
#-> Hello, Kimmie
# Calling the function with positional data raises an error.
print(concat("Hello, ", "Coleen"))
Traceback (most recent call last):
print(concat("Hello, ", "Coleen"))
TypeError: concat() takes 0 positional arguments but 2 were given
Os valores por omissão de um ou mais argumentos podem ser indicados na lista de parâmetros. Isto permite chamar a função com menos argumentos, se for preciso. Os valores por omissão podem ser substituídos chamando a função com um novo valor de argumento:
# Function with default argument values.
def concat(greeting, name="you", punctuation="!"):
return f"{greeting}, {name}{punctuation}"
print(concat("Hello"))
#-> Hello, you!
# Overriding the default values
print(concat("Hello", name="Polly", punctuation="."))
#-> Hello, Polly.
Os argumentos podem ser posicionais ou nomeados se não se usarem os operadores / nem * nas definições dos parâmetros.
Em alternativa, os argumentos posicionais ou nomeados podem ser colocados entre os parâmetros apenas posicionais, à esquerda, e os parâmetros apenas nomeados, à direita:
# Position-only argument followed by position-or-keyword, followed by keyword-only.
def concat(greeting, /, name, *, ending):
return f"{greeting}{name}{ending}"
print(concat("Hello, ", "Mark", ending="!"))
#-> Hello, Mark!
print(concat("Hello, ", name="Rachel", ending="!"))
#-> Hello, Rachel!
print(concat(greeting="Hello, ", name="JoJo", ending="!"))
Traceback (most recent call last):
print(concat(greeting="Hello, ", name="JoJo", ending="!"))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting'
*argsOs exemplos de código usam frequentemente uma definição de função parecida com a seguinte:
def my_function(*args, **kwargs):
# code snipped
*args é um nome com duas partes que representa um tuple com um número indefinido de argumentos posicionais separados, também conhecido como variadic argument.
args é o nome dado ao tuple de argumentos, mas podia ser qualquer outro nome válido em Python, como my_args, arguments, etc.
O * é o operador que transforma o conjunto de argumentos separados num tuple.
Se já alguma vez desempacotaste um tuplo, podes achar confuso o * em *args.
O * numa definição de parâmetro, em vez de desempacotar um tuplo, converte um ou mais argumentos posicionais num tuplo.
Dizemos que o operador * está sobrecarregado, pois tem comportamentos diferentes em contextos diferentes.
Por exemplo, o * é usado para a multiplicação, é usado para desempacotar e é usado para definir um número arbitrário de parâmetros posicionais.
Como é possível iterar sobre um tuple, o args pode ser passado a qualquer outra função que aceite um iterável.
Embora o *args apareça frequentemente associado ao **kwargs, não tem de ser assim:
def add(*args):
# args is passed to the sum function, which iterates over it.
return sum(args)
print(add(1, 2, 3))
#-> 6
Se o *args vier depois de um ou mais argumentos posicionais, então o *args será o que sobra depois desses argumentos posicionais:
def add(first, *args):
# first will be 1, leaving the values 2 and 3 in *args
return first + sum(args)
print(add(1, 2, 3))
#-> 6
Se um ou mais argumentos por omissão forem definidos depois do *args, ficam separados dos valores do *args:
def add(first, *args, last=0):
return first + sum(args) + last
print(add(1, 2, 3))
#-> 6
print(add(1, 2, 3, last=4))
#-> 10
# This uses the unpacking operator * to separate the list elements into positional arguments.
# It does not have the same behavior as the * (packing) in *args.
print(add(*[1, 2, 3]))
#-> 6
Repara que, quando um argumento já está dentro de um iterable (como um tuple ou uma list), é preciso desempacotá-lo antes de o passar a uma função que aceita um número arbitrário de argumentos separados.
Isto faz-se com o *, que é o operador de desempacotamento.
Neste contexto, o * desempacota o contentor nos seus elementos separados, que depois são transformados pelo *args num tuple.
Quando só há argumentos posicionais, a operação de desempacotamento tem de dar origem ao mesmo número de argumentos que os parâmetros formais definidos.
Sem desempacotar a lista passada a add, o programa daria erro:
def add(first, *args, last=0):
return first + sum(args) + last
print(add([1, 2, 3]))
Traceback (most recent call last):
print(add([1, 2, 3]))
return first + sum(args) + last
TypeError: can only concatenate list (not "int") to list
**kwargs**kwargs é um nome com duas partes que representa um número indefinido de pares chave-valor distintos como argumentos.
kwargs é o nome do conjunto de argumentos e podia ser qualquer outro nome, como my_args, arguments, etc.
O ** transforma o conjunto de argumentos nomeados num dictionary de pares {argument name: argument value}.
Como é possível iterar sobre um dicionário, o kwargs pode ser passado a qualquer outra função que aceite um iterável.
Embora o **kwargs apareça frequentemente associado ao *args, não tem de ser assim:
def add(**kwargs):
return sum(kwargs.values())
print(add(one=1, two=2, three=3))
#-> 6
Repara que o método dict.values() é chamado para iterar sobre os values do dicionário kwargs.
Ao iterar sobre um dicionário, o comportamento por omissão é iterar sobre as keys, por isso é preciso indicar dict.values() explicitamente:
def concat(**kwargs):
# Join concatenates the tuples from `kwargs.items()`
return " ".join((str(item) for item in kwargs.items()))
print(concat(one=1, two=2, three=3))
#-> ('one', 1) ('two', 2) ('three', 3)