E731不指定lambda表达式,使用def

时间:2014-07-29 07:26:14

标签: python lambda pep

每当我使用lambda表达式时,我都会收到此pep8警告。是不是建议使用lambda表达式?如果不是为什么?

4 个答案:

答案 0 :(得分:175)

您遇到的PEP-8中的建议是:

  

始终使用def语句而不是赋值语句   将lambda表达式直接绑定到名称。

     

是:

def f(x): return 2*x 
     

没有

f = lambda x: 2*x 
     

第一个表单表示结果的名称   函数对象特别是'f'而不是泛型'< lambda>'。   这对于回溯和字符串表示更有用   一般。赋值语句的使用消除了唯一   lambda表达式可以提供一个明确的def语句   (即它可以嵌入更大的表达式中)

将lambdas分配给名称基本上只是复制def的功能 - 一般来说,最好采取单一方式来避免混淆并提高清晰度。

lambda的合法用例是你想要在不指定函数的情况下使用函数的地方,例如:

sorted(players, key=lambda player: player.rank)

对于简单操作,the operator moduleattrgetteritemgettermethodcaller中提供了一些有用的选项,这些选项通常可以取代仅访问属性的项目符号(项目) s)和调用方法。

例如,上面的内容可以operator.attrgetter完成,如下所示:

sorted(players, key=operator.attrgetter('rank'))

答案 1 :(得分:95)

这是故事,我有一个简单的lambda函数,我使用了两次。

a = map(lambda x : x + offset, simple_list)
b = map(lambda x : x + offset, another_simple_list)

这仅仅是为了表示,我遇到了几个不同版本。

现在,为了保持干燥,我开始重用这个常见的lambda。

f = lambda x : x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)

此时我的代码质量检查器抱怨lambda是一个命名函数,所以我把它转换成一个函数。

def f(x):
    return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)

现在检查器抱怨函数必须由前后一个空行限定。

def f(x):
    return x + offset

a = map(f, simple_list)
b = map(f, another_simple_list)

这里我们现在有6行代码而不是原来的2行代码,可读性没有增加,并且没有增加pythonic。此时,代码检查器会抱怨没有docstrings的函数。

在我看来,这个规则可以更好地避免和破坏,当它有意义时,运用你的判断。

答案 2 :(得分:21)

Lattyware是绝对正确的:基本上PEP-8要求你避免像

这样的事情
f = lambda x: 2 * x

而是使用

def f(x):
    return 2 * x

但是,正如最近的bugreport(2014年8月)所述,以下声明现已符合:

a.f = lambda x: 2 * x
a["f"] = lambda x: 2 * x

由于我的PEP-8检查器尚未正确实现,我暂时关闭了E731。

答案 3 :(得分:2)

我还遇到了甚至无法使用def(ined)函数的情况。

class SomeClass(object):
  # pep-8 does not allow this
  f = lambda x: x + 1  # NOQA

  def not_reachable(self, x):
    return x + 1

  @staticmethod
  def also_not_reachable(x):
    return x + 1

  @classmethod
  def also_not_reachable(cls, x):
    return x + 1

  some_mapping = {
      'object1': {'name': "Object 1", 'func': f},
      'object2': {'name': "Object 2", 'func': some_other_func},
  }

在这种情况下,我真的想制作一个属于该类的映射。映射中的某些对象需要相同的功能。将命名函数放在类之外是不合逻辑的。 我还没有找到一种从类体内部引用方法(staticmethod,classmethod或normal)的方法。运行代码时,SomeClass尚不存在。所以从课堂上引用它也是不可能的。