Попередження про клітинку var-from-loop від Pylint


91

Для наступного коду:

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

Пілінт повідомив про помилку:

Змінна комірки sort_key, визначена у циклі (cell-var-from-loop)

Хтось міг би натякнути, що тут відбувається? З вихідного коду pylint опис:

Змінна, яка використовується у закритті, визначається у циклі. Це призведе до того, що у всіх закриттях буде використано одне і те ж значення для закритої змінної.

Але я не маю уявлення, що це означає. Хтось може навести приклад проблеми?


Що це за предмет results? Звичайний список? Щось ще?
Кевін

1
Дивіться , наприклад , stackoverflow.com/q/12423614/3001761
jonrsharpe

@Kevin, наприклад, результати = [{key: value}, {key: value} ...]
xis

В порядку. У цьому випадку я погоджуюсь з chepner, що вам не потрібно турбуватися про попередження тут.
Кевін

Відповіді:


102

Ім'я sort_keyв тілі lambdaзаповіту буде шукатись, коли функція буде фактично викликана, тому воно побачить значення, яке sort_keyбуло нещодавно. Оскільки ви телефонуєте sortнегайно, значення sort_keyне зміниться до того, як буде використано отриманий об'єкт функції, тому ви можете безпечно ігнорувати попередження. Щоб вимкнути його, ви можете зробити sort_keyзначення параметра за замовчуванням для lambda:

results.sort(key=lambda k, sk=sort_key: get_from_dot_path(k, sk),
             reverse=(order == -1))

5
Я б помилявся, вирішуючи проблему, замість ігноруючи попередження. Якщо можливо, я б використав key=partial(get_from_dot_path, foo=sort_key)замість лямбда-виразу (припускаючи, що існує якесь ім'я параметра foo, get_from_dot_pathяке можна використовувати для аргументу ключового слова; partialдозволяє лише заповнення позиційних параметрів виключно зліва).
Чепнер

1
Ах, я не розумів, що це може виправити, я думав, що вони рівнозначні; у такому випадку я згоден.
timdiels

3
майте на увазі, що в даний час фокус не завжди спрацьовує github.com/PyCQA/pylint/issues/3107
Даніель Піньоль,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.