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.
- Definiçãouma lista padrão é criada
- Chamada Aa lista compartilhada vira ['a']
- Chamada Ba mesma lista vira ['a', 'b']
- Ausência explícitaNone faz cada chamada criar uma lista
Exemplo mínimo
Deslize para ver todo o código
def collect(value, items=[]):
items.append(value)
return itemsdef collect(value, items=None):
if items is None:
items = []
items.append(value)
return itemsO 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.
- Chame a função duas vezes sem fornecer a lista opcional.
- Verifique se o segundo resultado contém o item da primeira chamada.
- Troque a lista padrão por None e crie a lista somente quando items is None.
- 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.