Cell-Var-From-Loop-Warnung von Pylint

89

Für den folgenden Code:

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

Pylint hat einen Fehler gemeldet:

Zellvariable sort_key in Schleife definiert (cell-var-from-loop)

Könnte jemand einen Hinweis geben, was hier passiert? Aus dem Pylint-Quellcode lautet die Beschreibung:

Eine in einem Abschluss verwendete Variable wird in einer Schleife definiert. Dies führt dazu, dass alle Abschlüsse denselben Wert für die geschlossene Variable verwenden.

Aber ich habe keine Ahnung, was es bedeutet. Könnte jemand ein Beispiel für das Problem geben?

xis
quelle
Was für ein Objekt ist das results? Gewöhnliche Liste? Etwas anderes?
Kevin
1
Siehe z. B. stackoverflow.com/q/12423614/3001761
jonrsharpe
@ Kevin zB Ergebnisse = [{Schlüssel: Wert}, {Schlüssel: Wert} ...]
xis
OK. In diesem Fall stimme ich chepner zu, dass Sie sich hier keine Sorgen um die Warnung machen müssen.
Kevin

Antworten:

97

Der Name sort_keyim Hauptteil von lambdawird nachgeschlagen, wenn die Funktion tatsächlich aufgerufen wird, sodass sort_keyder zuletzt angegebene Wert angezeigt wird. Da Sie sortsofort aufrufen , sort_keyändert sich der Wert von nicht, bevor das resultierende Funktionsobjekt verwendet wird, sodass Sie die Warnung sicher ignorieren können. Um es zum Schweigen zu bringen, können Sie sort_keyden Standardwert eines Parameters wie folgt festlegen lambda:

results.sort(key=lambda k, sk=sort_key: get_from_dot_path(k, sk),
             reverse=(order == -1))
chepner
quelle
4
Ich würde mich irren, das Problem zu beheben, anstatt die Warnung zu ignorieren. Wenn möglich, würde ich key=partial(get_from_dot_path, foo=sort_key)anstelle des Lambda-Ausdrucks verwenden (vorausgesetzt, es ist ein Parametername foodefiniert get_from_dot_path, den Sie für ein Schlüsselwortargument verwenden können; partialerlaubt nur das Ausfüllen von Positionsparametern ausschließlich von links).
Chepner
1
Ah, ich wusste nicht, dass dies das Problem beheben würde. Ich dachte, sie wären gleichwertig. in diesem Fall stimme ich zu.
Timdiels
3
Beachten Sie, dass der Trick derzeit nicht immer funktioniert. github.com/PyCQA/pylint/issues/3107
Daniel Pinyol