问题:E731不分配lambda表达式,使用def
每当我使用lambda表达式时,都会收到此pep8警告。不建议使用lambda表达式吗?如果不是,为什么?
回答 0
您遇到的PEP-8中的建议是:
始终使用def语句代替将lambda表达式直接绑定到名称的赋值语句。
是:
def f(x): return 2*x
没有:
f = lambda x: 2*x
第一种形式表示结果函数对象的名称专门为’f’而不是通用的'<lambda>’。通常,这对于回溯和字符串表示形式更为有用。使用赋值语句消除了lambda表达式可以提供的优于显式def语句的唯一好处(即,它可以嵌入到较大的表达式中)
为名称分配lambda基本上只是复制了def
– 的功能-通常,最好以一种单一的方式进行操作以避免混淆并提高清晰度。
lambda的合法用例是您要在不分配功能的情况下使用该功能,例如:
sorted(players, key=lambda player: player.rank)
通常,反对这样做的主要理由是def
语句将导致更多的代码行。我对此的主要回应是:是的,这很好。除非您是打高尔夫球的人,否则不应该减少行数:一目了然。
回答 1
这是一个故事,我有一个简单的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的代码。在这一点上,代码检查器抱怨该函数没有文档字符串。
在我看来,最好在合理的情况下避免并破坏该规则,请运用您的判断。
回答 2
Lattyware是完全正确的:基本上,PEP-8希望您避免诸如此类的事情
f = lambda x: 2 * x
而是使用
def f(x):
return 2 * x
但是,正如最近 bug报告(2014年8月),语句,如下面现在是否符合:
a.f = lambda x: 2 * x
a["f"] = lambda x: 2 * x
由于我的PEP-8检查器尚未正确实现此功能,因此我暂时关闭了E731。
回答 3
我还遇到了甚至无法使用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},
}
在这种情况下,我真的很想做一个属于该类的映射。映射中的某些对象需要相同的功能。将命名函数放在类之外是不合逻辑的。我还没有找到从类主体内部引用方法(静态方法,类方法或普通方法)的方法。运行代码时,尚不存在SomeClass。因此,也不可能从类中引用它。