Aviso Cell-var-from-loop do Pylint

94

Para o seguinte código:

for sort_key, order in query_data['sort']:
    results.sort(key=lambda k: get_from_dot_path(k, sort_key),
                 reverse=(order == -1))

Pylint relatou um erro:

Variável de célula sort_key definida em loop (cell-var-from-loop)

Alguém poderia dar uma dica do que está acontecendo aqui? A descrição do código-fonte do pylint é:

Uma variável usada em um encerramento é definida em um loop. Isso resultará em todos os fechamentos usando o mesmo valor para a variável fechada.

Mas eu não tenho ideia do que isso significa. Alguém poderia dar um exemplo do problema?

xis
fonte
Que tipo de objeto é results? Lista comum? Algo mais?
Kevin
1
Consulte, por exemplo, stackoverflow.com/q/12423614/3001761
jonrsharpe
@Kevin, por exemplo, resultados = [{chave: valor}, {chave: valor} ...]
xis
Está bem. Nesse caso, concordo com o chepner que você não precisa se preocupar com o aviso aqui.
Kevin

Respostas:

106

O nome sort_keyno corpo do lambdaserá pesquisado quando a função for realmente chamada, para que ele veja o valor sort_keymais recente. Como você está chamando sortimediatamente, o valor de sort_keynão será alterado antes que o objeto de função resultante seja usado, portanto, você pode ignorar o aviso com segurança. Para silenciá-lo, você pode definir sort_keyo valor padrão de um parâmetro para lambda:

results.sort(key=lambda k, sk=sort_key: get_from_dot_path(k, sk),
             reverse=(order == -1))
chepner
fonte
5
Eu erraria ao corrigir o problema em vez de ignorar o aviso. Se possível, eu usaria em key=partial(get_from_dot_path, foo=sort_key)vez da expressão lambda (supondo que haja algum nome de parâmetro foodefinido por get_from_dot_pathque você possa usar como um argumento de palavra-chave; partialpermite apenas preencher parâmetros posicionais exclusivamente da esquerda).
chepner
1
Ah, eu não sabia que isso resolveria, pensei que eram equivalentes; nesse caso, eu concordo.
timdiels
3
esteja ciente de que atualmente o truque nem sempre funciona github.com/PyCQA/pylint/issues/3107
Daniel Pinyol