Avertissement Cell-var-from-loop de Pylint

91

Pour le code suivant:

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

Pylint a signalé une erreur:

Variable de cellule sort_key définie dans la boucle (cell-var-from-loop)

Quelqu'un pourrait-il donner une idée de ce qui se passe ici? À partir du code source de pylint, la description est:

Une variable utilisée dans une fermeture est définie dans une boucle. Cela entraînera toutes les fermetures en utilisant la même valeur pour la variable fermée.

Mais je n'ai aucune idée de ce que cela signifie. Quelqu'un pourrait-il donner un exemple du problème?

xis
la source
Quel genre d'objet est results? Liste ordinaire? Autre chose?
Kevin
1
Voir par exemple stackoverflow.com/q/12423614/3001761
jonrsharpe
@Kevin eg results = [{key: value}, {key: value} ...]
xis
D'accord. Dans ce cas, je suis d'accord avec Chepner pour dire que vous n'avez pas à vous soucier de l'avertissement ici.
Kevin

Réponses:

102

Le nom sort_keydans le corps du lambdasera recherché lorsque la fonction est réellement appelée, donc il verra la valeur la sort_keyplus récente. Comme vous appelez sortimmédiatement, la valeur de sort_keyne changera pas avant que l'objet fonction résultant ne soit utilisé, vous pouvez donc ignorer l'avertissement en toute sécurité. Pour le désactiver, vous pouvez définir sort_keyla valeur par défaut d'un paramètre sur lambda:

results.sort(key=lambda k, sk=sort_key: get_from_dot_path(k, sk),
             reverse=(order == -1))
chepner
la source
5
J'aurais tort de résoudre le problème au lieu d'ignorer l'avertissement. Si possible, j'utiliserais à la key=partial(get_from_dot_path, foo=sort_key)place de l'expression lambda (en supposant qu'il existe un nom de paramètre foodéfini par get_from_dot_pathcelui-ci que vous pouvez utiliser pour un argument de mot-clé; partialpermet uniquement de remplir les paramètres de position exclusivement à partir de la gauche).
chepner
1
Ah je ne savais pas que ça réglerait le problème, je pensais qu'ils étaient équivalents; dans ce cas, je suis d'accord.
timdiels
3
sachez qu'actuellement, l'astuce ne fonctionne pas toujours github.com/PyCQA/pylint/issues/3107
Daniel Pinyol