每当我使用lambda表达式时,我都会得到这个pep8警告。不建议使用lambda表达式吗?如果不是,为什么?
你在PEP-8中遇到的建议是:
总是使用def语句而不是赋值语句 将lambda表达式直接绑定到名称 是的: def f(x): return 2*x 没有: f = lambda x: 2*x 第一种形式表示结果的名称 函数对象是特定的'f',而不是泛型的'<lambda>'。 中的回溯和字符串表示更有用 将军。赋值语句的使用消除了鞋底 lambda表达式相对于显式def语句的优势 (即它可以嵌入到更大的表达式中)
总是使用def语句而不是赋值语句 将lambda表达式直接绑定到名称
是的:
def f(x): return 2*x
没有:
f = lambda x: 2*x
第一种形式表示结果的名称 函数对象是特定的'f',而不是泛型的'<lambda>'。 中的回溯和字符串表示更有用 将军。赋值语句的使用消除了鞋底 lambda表达式相对于显式def语句的优势 (即它可以嵌入到更大的表达式中)
将lambdas分配给名称基本上只是复制了def的功能——一般来说,最好用一种方式来做某事,以避免混乱并增加清晰度。
def
lambda的合法用例是你想使用一个函数而不给它赋值,例如:
sorted(players, key=lambda player: player.rank)
一般来说,反对这样做的主要论点是def语句将导致更多的代码行。我对此的主要回答是:是的,这很好。除非你在打代码高尔夫,否则尽量减少行数不是你应该做的事情:追求清晰而不是简短。
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。
故事是这样的,我有一个简单的函数我用了两次。
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)
现在检查器抱怨一个函数前后必须有一个空行。
现在我们有6行代码而不是原来的2行,可读性没有增加,python化也没有增加。此时,代码检查器抱怨函数没有文档字符串。
在我看来,最好避免这个规则,当它有意义时,使用你的判断。
我还遇到过一种情况,在这种情况下,甚至不可能使用已定义的函数。
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}, }
这适用于我在一个类,删除lambda表达式和使用def代替,改变这个…
def set_every(self, every: int = 1, time_unit: int = TimeUnit.Day): every_func = lambda x: "*" if x == 1 else "*/" + str(x) if TimeUnit.has_value(time_unit): self.month_of_year = "*" self.day_of_month = "*" if time_unit != TimeUnit.Day else every_func(every) self.day_of_week = "*" if time_unit != TimeUnit.Week else every_func(every)
由这个……
def set_every(self, every: int = 1, time_unit: int = TimeUnit.Day): def every_func(x: int) -> str: return "*" if x == 1 else "*/" + str(x) if TimeUnit.has_value(time_unit): self.month_of_year = "*" self.day_of_month = "*" if time_unit != TimeUnit.Day else every_func(every) self.day_of_week = "*" if time_unit != TimeUnit.Week else every_func(every)