每当我使用lambda表达式时,我都会收到此pep8警告。是不是建议使用lambda表达式?如果不是为什么?
答案 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
module在attrgetter
,itemgetter
和methodcaller
中提供了一些有用的选项,这些选项通常可以取代仅访问属性的项目符号(项目) 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尚不存在。所以从课堂上引用它也是不可能的。