Depuração prática, passo a passo

Uma lista padrão mutável pode guardar dados de chamadas anteriores

O Python cria o valor padrão quando define a função, não a cada chamada. Se esse valor for uma lista, várias chamadas podem compartilhar a mesma lista sem deixar isso claro.

DoesItHold Editorial · · revisado em · guide-python-defaults-001

Resposta direta

Use None para indicar que nenhuma lista foi fornecida. Depois crie uma lista nova dentro da função somente nesse caso.

Quando a instrução def é executada, o Python avalia os valores padrão uma vez. Uma lista, um dicionário ou um conjunto criado ali é reutilizado sempre que a pessoa chama a função sem fornecer esse argumento. Alterar o objeto em uma chamada muda o que a próxima recebe.

O comportamento não é aleatório. Chame a função duas vezes sem passar a lista. Se o segundo resultado trouxer também o item da primeira chamada, você confirmou que o valor padrão está sendo compartilhado.

Rastreie a falha
  1. Definiçãouma lista padrão é criada
  2. Chamada Aa lista compartilhada vira ['a']
  3. Chamada Ba mesma lista vira ['a', 'b']
  4. Ausência explícitaNone faz cada chamada criar uma lista
O defeito é a reutilização do objeto: quando a lista é omitida, todas as chamadas usam a lista criada com def. Usar None faz a função criar uma lista nova em cada chamada.

Exemplo mínimo

Deslize para ver todo o código

Com defeito
def collect(value, items=[]):
    items.append(value)
    return items
Corrigido
def collect(value, items=None):
    if items is None:
        items = []
    items.append(value)
    return items

O que muda: Duas chamadas que omitem o argumento deixam de compartilhar um objeto; uma coleção fornecida explicitamente continua sendo alterada como solicitado.

Método de depuração

Repita a chamada sem o argumento, observe se os resultados se acumulam e mova a criação da lista para dentro da função.

  1. Chame a função duas vezes sem fornecer a lista opcional.
  2. Verifique se o segundo resultado contém o item da primeira chamada.
  3. Troque a lista padrão por None e crie a lista somente quando items is None.
  4. Teste também uma lista vazia fornecida explicitamente para confirmar que ela continua sendo usada.

Correção incorreta comum

Copiar a lista apenas no return não impede que o objeto compartilhado seja alterado durante a chamada. Usar items = items or [] também descarta uma lista vazia que a pessoa forneceu de propósito.

Limites e casos-limite

Compartilhar um valor padrão pode ser intencional em um cache, mas isso deixa o estado escondido e difícil de reiniciar. Prefira um cache explícito ou um recurso padrão da linguagem, deixando claro quem controla os dados e por quanto tempo.

Fontes