Ostrzeżenie Cell-var-from-loop od Pylint

91

Dla następującego kodu:

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

Pylint zgłosił błąd:

Zmienna komórki sort_key zdefiniowana w pętli (cell-var-from-loop)

Czy ktoś mógłby podpowiedzieć, co się tutaj dzieje? Z kodu źródłowego pylint opis to:

Zmienna używana w zamknięciu jest definiowana w pętli. Spowoduje to, że wszystkie zamknięcia będą używać tej samej wartości zmiennej zamkniętej.

Ale nie mam pojęcia, co to znaczy. Czy ktoś mógłby podać przykład problemu?

xis
źródło
Co to za przedmiot results? Zwykła lista? Coś innego?
Kevin
1
Patrz np stackoverflow.com/q/12423614/3001761
jonrsharpe
@Kevin np. Wyniki = [{klucz: wartość}, {klucz: wartość} ...]
xis
Ok. W takim razie zgadzam się z Chepnerem, że nie musisz się martwić o ostrzeżenie tutaj.
Kevin

Odpowiedzi:

102

Nazwa sort_keyw treści lambdazostanie wyszukana, gdy funkcja zostanie faktycznie wywołana, więc zobaczy wartość, sort_keyktórą ostatnio miała. Ponieważ wywołujesz sortnatychmiast, wartość sort_keynie zmieni się przed użyciem wynikowego obiektu funkcji, więc możesz bezpiecznie zignorować ostrzeżenie. Aby go wyciszyć, możesz ustawić sort_keydomyślną wartość parametru na lambda:

results.sort(key=lambda k, sk=sort_key: get_from_dot_path(k, sk),
             reverse=(order == -1))
Chepner
źródło
5
Błądziłbym po stronie rozwiązania problemu, zamiast ignorować ostrzeżenie. Jeśli to możliwe, użyłbym key=partial(get_from_dot_path, foo=sort_key)zamiast wyrażenia lambda (zakładając, że jest foozdefiniowana jakaś nazwa parametru get_from_dot_path, którą możesz użyć jako argumentu słowa kluczowego; partialpozwala tylko na wypełnianie parametrów pozycyjnych wyłącznie z lewej strony).
chepner
1
Ach, nie zdawałem sobie sprawy, że to wszystko naprawi, myślałem, że są równoważne; w takim razie zgadzam się.
timdiels
3
pamiętaj, że obecnie sztuczka nie zawsze działa github.com/PyCQA/pylint/issues/3107
Daniel Pinyol