来自 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 最近的值。由于您立即调用sortsort_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 表达式(假设有一些参数名称 fooget_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'”

pylint

pylint & jenkins

如何使用 Pylint 来规范 Python 代码风格

如何使用 Pylint 来规范 Python 代码风格

pylint之代码静态检查