Como usar e anotar argumentos por defeito em funções Python

O negócio

A definição de um argumento padrão numa definição de função Python faz com que o valor padrão seja utilizado se o argumento for omitido durante uma chamada de função.

Os seguintes detalhes são descritos abaixo.

  • Definição de Argumentos por Defeito
  • Restrições sobre a posição dos argumentos por defeito
  • Note que quando uma lista ou dicionário é utilizado como valor padrão

Definição de Argumentos por Defeito

Se nome do argumento = valor por defeito na definição da função, o valor por defeito será utilizado quando o argumento correspondente for omitido.

def func_default(arg1, arg2='default_x', arg3='default_y'):
    print(arg1)
    print(arg2)
    print(arg3)

func_default('a')
# a
# default_x
# default_y

func_default('a', 'b')
# a
# b
# default_y

func_default('a', arg3='c')
# a
# default_x
# c

Restrições sobre a posição dos argumentos por defeito

Colocar um argumento por defeito antes de um argumento normal (um argumento para o qual não é especificado um valor por defeito) ao definir uma função resulta num erro.
SyntaxError

# def func_default_error(arg2='default_a', arg3='default_b', arg1):
#     print(arg1)
#     print(arg2)

# SyntaxError: non-default argument follows default argument

Note que quando uma lista ou dicionário é utilizado como valor padrão

Se um objecto actualizável (mutável) como uma lista ou dicionário for especificado como o valor por defeito, esse objecto será criado quando a função for definida. Então, quando a função é chamada sem o argumento correspondente, o mesmo objecto é utilizado.

Os valores do argumento por defeito são avaliados da esquerda para a direita quando a definição da função é executada. Isto significa que a expressão do argumento padrão é avaliada apenas uma vez quando a função é definida, e o mesmo valor “calculado” é utilizado para cada chamada.
8.7. Function definitions — Python 3.10.2 Documentation

Assim, por exemplo, se for definida uma função que toma uma lista ou dicionário como argumento padrão e lhe acrescenta elementos, e é chamada várias vezes sem esse argumento, os elementos serão acrescentados repetidamente ao mesmo objecto.

Exemplo para uma listagem.

def func_default_list(l=[0, 1, 2], v=3):
    l.append(v)
    print(l)

func_default_list([0, 0, 0], 100)
# [0, 0, 0, 100]

func_default_list()
# [0, 1, 2, 3]

func_default_list()
# [0, 1, 2, 3, 3]

func_default_list()
# [0, 1, 2, 3, 3, 3]

Exemplo para um dicionário.

def func_default_dict(d={'default': 0}, k='new', v=100):
    d[k] = v
    print(d)

func_default_dict()
# {'default': 0, 'new': 100}

func_default_dict(k='new2', v=200)
# {'default': 0, 'new': 100, 'new2': 200}

É criado um novo objecto de cada vez que a função é chamada.

def func_default_list_none(l=None, v=3):
    if l is None:
        l = [0, 1, 2]
    l.append(v)
    print(l)

func_default_list_none()
# [0, 1, 2, 3]

func_default_list_none()
# [0, 1, 2, 3]
Copied title and URL