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

Python E731不指定lambda表达式,请使用def,python,lambda,pep,Python,Lambda,Pep,每当我使用lambda表达式时,都会收到此pep8警告。不建议使用lambda表达式吗?如果不是,原因是什么?您遇到的建议是: 始终使用def语句而不是 将lambda表达式直接绑定到名称 是的: def f(x): return 2*x 否: f = lambda x: 2*x 第一种形式表示结果的名称 函数对象具体为“f”,而不是泛型“”。 这对于中的回溯和字符串表示更有用 将军。使用赋值语句消除了唯一的 lambda表达式可以提供优于显式def语句的好处 (即,它可以嵌入到更大的表

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

您遇到的建议是:

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

是的:

def f(x): return 2*x 
否:

f = lambda x: 2*x 
第一种形式表示结果的名称 函数对象具体为“f”,而不是泛型“”。 这对于中的回溯和字符串表示更有用 将军。使用赋值语句消除了唯一的 lambda表达式可以提供优于显式def语句的好处 (即,它可以嵌入到更大的表达式中)

将lambda分配给名称基本上只是复制了
def
的功能,一般来说,最好用一种方法来避免混淆并提高清晰度

lambda的合法使用情形是您希望在不分配函数的情况下使用函数,例如:

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

通常,反对这样做的主要理由是
def
语句将导致更多的代码行。我对此的主要回应是:是的,那很好。除非你是在打代码高尔夫,否则尽量减少线的数量不是你应该做的事情:在短时间内进行清理。

Lattyware绝对正确:基本上希望你避免类似的事情

f = lambda x: 2 * x
而是使用

def f(x):
    return 2 * x
然而,正如最近一次(2014年8月)所述,以下声明现已符合要求:

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

由于我的PEP-8检查器还没有正确实现这一点,我暂时关闭了E731。

故事是这样的,我有一个简单的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也没有增加。此时,代码检查器抱怨函数没有docstring


在我看来,最好避免和打破这条规则,当它有意义时,运用你的判断

我还遇到了一种甚至无法使用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还不存在。因此,从类中引用它也是不可能的

我看不出情况有多糟。回溯仍将包括错误的行号和源文件。一个可能说“f”,而另一个说“lambda”。也许lambda错误更容易扫描,因为它不是一个单字符函数名,或者不是一个名称不好的长名称?@g33kz0r当然,如果您假设其余代码的质量很差,那么遵循约定不会给您带来太多好处。一般来说,不,这不是世界末日,但这仍然是一个坏主意。这个答案不是很有帮助,因为当通过PEP8检查器运行建议的使用
def
的方法时,一行(def)上会出现
E704条多条语句,如果将其分成两行,则会出现
E301预期的一条空行,找到0
:-/I我同意应该拆分它。我的观点是:a)上面的答案代码中没有拆分,导致E704;b)如果拆分,则需要在上面有一个难看的空行,以避免E301。当我想强调纯函数(无副作用)时,我使用lambdas,有时我必须在两个位置使用相同的函数,即groupby和sort together。因此我忽略了这个约定。即使使用
def
,PEP8检查器也会抱怨
E301需要1个空行,发现0
,因此您必须在它前面添加一个难看的空行。
a=[x+简单列表中x的偏移量]
。无需在此处使用
map
lambda
。@Georgy我认为重点是将
x+偏移量
部分移动到一个抽象位置,该位置可以在不更改多行代码的情况下进行更新。对于您提到的列表理解,您仍然需要两行代码,其中包含
x+offset
,它们现在应该在列表理解中。为了按照作者的意愿提取这些数据,除了
def
lambda
之外,你还需要一个
def
lambda
@Julian;
f=partial(operator.add,offset)
然后
a=list(map(f,simple_list))
。那么
def(x):返回x+offset
(即,在单行上定义的简单函数)?至少对于flake8,我没有收到关于空行的投诉。@Julian在某些情况下,您可以使用嵌套理解:
a,b=[[x+offset for x lst]for lst In(简单列表,另一个简单列表)]
您可以将映射定义中的
也\u not \u reachable
称为
SomeClass。也\u not \u reachable
我不知道您想在这里说明什么。对于meNope,在2.7和3.5中,您的每个函数名都与
f
一样可访问。除了lambda函数之外,所有函数都是不可访问的类主体中的rom。如果尝试访问某些映射对象中的其中一个函数,您将得到一个AttributeError:type对象“SomeClass”没有属性“…”。@simP所有这些函数都是完全可访问的。
@staticmethod
和<