Argumentos de funções em Python

argumentos-1_abertura

Em Python, além do modo convencional de se fazer a passagem de argumentos para as funções, há outras formas onde é possível pré-definir o valor de um argumento ou mesmo permitir que ela (a função) possa receber quantidades arbitrárias de argumentos.

E isto aqui é um pequeno resumo do que pode ser feito.

Uma rápida revisão…

Em Python, uma função pode receber nenhum argumento e trabalhar, se for o caso, apenas com variáveis já definidas¹ ou então com aquelas que serão criadas dentro do seu escopo.

>>> def sem_argumentos():
...     return 1
...
>>> sem_argumentos()
1

Claro que (quase) sempre será preciso passar um…

>>> def um_argumento(i):
...     return i + i
...
>>> um_argumento(1)
2

…ou mais argumentos para a ela.

>>> def dois_argumentos(i, j):
...     return i + j
...
>>> dois_argumentos(1, 2)
3

Estes são chamados de argumentos posicionais pois os valores passados para a função serão atribuídos às variáveis na ordem (posição) em que estas foram declaradas.

(¹) Lembrando que as variáveis globais são, por padrão, apenas para leitura.

Argumentos com valor padrão

Porém, se um argumento recebe (quase) sempre o mesmo valor (e por algum motivo ele não pode ser uma variável global), é possível defini-lo diretamente na declaração da função.

>>> def argumentos_padrao(i, j=1):
...     return i + j
...
>>> argumentos_padrao(7)
8
>>> argumentos_padrao(7, 2)
9

Neste caso o primeiro argumento da função, que é posicional, será atribuído à variável “i” enquanto que o segundo, se existir, à variável “j” mas, no caso de ser omitido, o valor 1 será atribuído a ela. A principal vantagem é deixar a chamada da função mais limpa e também mais legível.

Ao mesmo tempo, torna mais fácil a manutenção já que o valor padrão se encontra registrado em um único ponto do código.

Argumentos com palavra chave

Subtópico, você pode passar argumentos com valores até para os argumentos posicionais bastando explicitar o nome da variável e até em uma ordem diferente daquela originalmente definida.

>>> def argumentos_padrao_2(i, j=0, k=0):
...     return i + j + k
...
>>> argumentos_padrao_2(1, k=2, j=1)
4
>>> argumentos_padrao_2(k=1, i=2, j=3)
6

E lembrando que há uma limitação aqui. Você não pode usar argumentos posicionais depois dos argumento com palavra chave “(j=0, k=1, 10)” e muito menos repetir um mesmo valor já definido nos argumentos posicionais “(10, i=10)”.

Lista arbitrária de argumentos

Neste caso todos os argumentos posicionais de uma função são empacotados e entregues à função dentro de uma tupla.

>>> def todos_os_argumentos(*args):
...     return sum(args)
...
>>> todos_os_argumentos(1, 2)
3
>>> todos_os_argumentos(1, 2, 3, 4, 5)
15

Ou apenas uma parte deles.

>>> def alguns_argumentos(i, *args):
...     return [i * j for j in args]
... 
>>> alguns_argumentos(10, 1, 2, 3, 4)
[10, 20, 30, 40]

Especificamente no caso da versão 3.x do Python, é possível usar argumentos com valores padrão mas estes deverão ser declarados antes do uso do “*args” e utilizados no final da chamada.

>>> def alguns_argumentos_com_padrao(i, j=1, *args):
...     return [j + i * k for k in args]
... 
>>> alguns_argumentos_com_padrao(10, 1, 2, 3, 4)
[11, 21, 31, 41]
>>> alguns_argumentos_com_padrao(10, 1, 2, 3, 4, j=2)
[12, 22, 32, 42]

Aliás, bons exemplos do uso de listas arbitrárias são as funções os.path.join() e também a print(), ambas da biblioteca padrão da linguagem.

Lista arbitrária de argumentos com palavra chave

Se argumentos arbitrários podem ser agrupados dentro de uma tupla, os argumentos com palavras chave podem ser entregues, total ou parcialmente, dentro de um dicionário.

>>> def argumentos_em_dicionario(**kargs):
...     for k, v in kargs.items():
...         print('{} = {}'.format(k, v))
... 
>>> argumentos_em_dicionario(nome='Fulano', idade=50, ativo=False)
nome = Fulano
idade = 50
ativo = False

Um bom exemplo disto são as chamadas do ORM do Django — peguei o mesmo exemplo da parte 2 do Exemplo em Django… 🙂

>>> e = Event(event='Segundo evento da agenda', \
... date='2018-04-13', \
... priority='1')

E você ainda pode usá-la em conjunto com a lista arbitrária de argumentos.

Concluindo

Só lembrando que os nomes “*args” e “**kargs” são bem mais uma convenção utilizada em Python do que necessariamente um nome que deve ser obrigatório utilizado — sim, servem para você saber do que se trata¹.

E lembrando que as funções mostradas nos exemplos acima, além da concat() (ver “concat.py”), estão disponíveis no repositório git deste blog no GitHub.

Até!

(¹) Assim como são “self” e “cls”, mas isto ficará para uma outra oportunidade.

Anúncios