来自 Pylint 的 Cell-var-from-loop 警告
Posted
技术标签:
【中文标题】来自 Pylint 的 Cell-var-from-loop 警告【英文标题】:Cell-var-from-loop warning from Pylint 【发布时间】:2014-10-08 11:43:18 【问题描述】:对于以下代码:
for sort_key, order in query_data['sort']:
results.sort(key=lambda k: get_from_dot_path(k, sort_key),
reverse=(order == -1))
Pylint 报错:
循环中定义的单元格变量 sort_key (cell-var-from-loop)
谁能提示这里发生了什么?来自pylint源代码的描述是:
闭包中使用的变量是在循环中定义的。 这将导致所有闭包使用相同的值 封闭变量。
但我不知道这意味着什么。谁能举例说明这个问题?
【问题讨论】:
results
是什么对象?普通名单?还有什么?
参见例如***.com/q/12423614/3001761
@Kevin 例如结果 = [key: value, key: value ...]
好的。在这种情况下,我同意 chepner 的观点,您不必担心这里的警告。
【参考方案1】:
lambda
的主体中的名称 sort_key
将在实际调用函数时进行查找,因此它会看到 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))
【讨论】:
我宁愿解决问题而不是忽略警告。如果可能的话,我会使用key=partial(get_from_dot_path, foo=sort_key)
而不是 lambda 表达式(假设有一些参数名称 foo
由 get_from_dot_path
定义,您可以将其用于关键字参数;partial
仅允许从左边)。
啊我没有意识到这会解决它,我认为它们是等价的;在这种情况下,我同意。
请注意,目前该技巧并不总是有效github.com/PyCQA/pylint/issues/3107
使用nonlocal
没有没有帮助,我不得不使用@chepner建议的partial()。【参考方案2】:
使用functools.partial():
import functools
results.sort(key=functools.partial(get_from_dot_path, foo=sort_key),
reverse=(order == -1))
【讨论】:
可以确认这不仅消除了警告,而且确实解决了问题。例如,尝试制作一个 lambda 列表打印范围 1,10 - 使用 lambda,它们都打印 9,使用 functools.partial 它们打印每个值以上是关于来自 Pylint 的 Cell-var-from-loop 警告的主要内容,如果未能解决你的问题,请参考以下文章
Pylint Error Message: “E1101: Module 'xxx' has no 'xxx' member'”