Python \*args e \*\*kwargs Simplificados - Guia Rápido Python

Eu não sei sobre você, mas toda vez que eu via alguma função com *args e **kwargs como parâmetros, eu ficava um pouco assustado. Eu até “usei” eles ao fazer algum trabalho de backend com Django sem entender nada. Se você é um desenvolvedor autodidata como eu, sei que você já passou por isso também.
Alguns meses atrás, decidi parar de ser preguiçoso e comecei a pesquisar sobre isso. Para minha surpresa, eles eram fáceis de entender ao brincar com o interpretador, mas não tanto ao ler sobre eles. Escrevi esta postagem tentando explicar args e kwargs da maneira que eu gostaria que alguém tivesse me explicado.
Fundamentos
A primeira coisa que você precisa saber é que *args e **kwargs permitem que você passe um número indefinido de arguments e keywords ao chamar uma function:
def some_function(*args, **kwargs):
pass
# chama some_function com qualquer número de argumentos
some_function(arg1, arg2, arg3)
# chama some_function com qualquer número de palavras-chave
some_function(key1=arg1, key2=arg2, key3=arg3)
# chama ambos, argumentos e palavras-chave
some_function(arg, key1=arg1)
# ou nenhum
some_function()
Em segundo lugar, as palavras args e kwargs são convenções. Isso significa que elas não são impostas pelo interpretador, mas são consideradas boas práticas na comunidade Python:
# Esta função funcionaria perfeitamente
def some_function(*arguments, **keywords):
pass
Uma nota sobre convenções
Mesmo que a função acima funcione, não o faça. As convenções existem para ajudá-lo a escrever código legível para você e para qualquer pessoa que possa se interessar pelo seu projeto. Outras convenções incluem a indentação de 4 espaços, comentários e imports. Ler o PEP 8 -- Style Guide for Python Code é altamente recomendado.
Então, como o Python sabe que queremos que nossa função aceite múltiplos argumentos e palavras-chave? Sim, as respostas são os operadores * e **.
Agora que cobrimos os fundamentos, vamos trabalhar com eles 👊.
args
Agora sabemos como passar múltiplos argumentos usando *args como um parâmetro para nossas funções, mas como trabalhamos com eles? É fácil: todos os argumentos estão dentro da variável args como uma tuple:
def some_function(*args):
print(f'Arguments passed: {args} as {type(args)}')
some_function('arg1', 'arg2', 'arg3')
# Arguments passed: ('arg1', 'arg2', 'arg3') as <class 'tuple'>
Podemos iterar sobre eles:
def some_function(*args):
for a in args:
print(a)
some_function('arg1', 'arg2', 'arg3')
# arg1
# arg2
# arg3
Acessar os elementos com um índice:
def some_function(*args):
print(args[1])
some_function('arg1', 'arg2', 'arg3') # arg2
Fatiamento (Slice):
def some_function(*args):
print(args[0:2])
some_function('arg1', 'arg2', 'arg3')
# ('arg1', 'arg2')
Tudo o que você faz com uma tuple, você pode fazer com args.
kwargs
Enquanto os argumentos estão na variável args, as palavras-chave estão dentro de kwargs, mas desta vez como um dictionary onde a chave é a palavra-chave:
def some_function(**kwargs):
print(f'keywords: {kwargs} as {type(kwargs)}')
some_function(key1='arg1', key2='arg2', key3='arg3')
# keywords: {'key1': 'arg1', 'key2': 'arg2', 'key3': 'arg3'} as <class 'dict'>
Novamente, podemos fazer com kwargs o mesmo que faríamos com qualquer dictionary.
Iterar sobre:
def some_function(**kwargs):
for key, value in kwargs.items():
print(f'{key}: {value}')
some_function(key1='arg1', key2='arg2', key3='arg3')
# key1: arg1
# key2: arg2
# key3: arg3
Usar o método get():
def some_function(key, **kwargs):
print(kwargs.get(key))
some_function('key3', key1='arg1', key2='arg2', key3='arg3')
# arg3
E muito mais =).
Conclusão
*args e **kwargs podem parecer assustadores, mas a verdade é que eles não são tão difíceis de entender e têm o poder de conceder muita flexibilidade às suas funções. Se você conhece tuples e dictionaries, você está pronto para começar.
Quer brincar com args e kwargs? Este é um Jupyter Notebook online para você experimentar.
Alguns exemplos fazem uso de f-strings, uma maneira relativamente nova de formatar strings no Python 3.6+. Aqui você pode ler mais sobre isso.