Answers:
您遇到的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
语句将导致更多的代码行。我对此的主要回应是:是的,这很好。除非您是打高尔夫球的人,否则不应该减少行数:一目了然。
def
通过PEP8检查器使用的方法时,您会得到E704 multiple statements on one line (def)
,如果将其分为两行,则会得到E301 expected 1 blank line, found 0
:-/
这是一个故事,我有一个简单的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的代码。在这一点上,代码检查器抱怨该函数没有文档字符串。
在我看来,最好在合理的情况下避免并破坏该规则,请运用您的判断。
a = [x + offset for x in simple_list]
。无需使用map
,lambda
这里。
x + offset
部分移动到一个抽象的位置,可以在不更改多行代码的情况下进行更新。就像您提到的列表理解一样,您仍然需要两行包含x + offset
它们的代码。为了按照作者的意愿将其删除,您需要一个def
或lambda
。
def
和lambda
一个也可以使用functools.partial:f = partial(operator.add, offset)
然后a = list(map(f, simple_list))
。
def f(x): return x + offset
(即,在一行上定义的简单函数)?至少对于flake8,我没有抱怨空白行。
a, b = [[x + offset for x lst] for lst in (simple_list, another_simple_list)]
我还遇到了甚至无法使用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。因此,也不可能从类中引用它。
also_not_reachable
在映射定义中将其称为SomeClass.also_not_reachable
f
对于我来说,您的每个函数名称都可以像2.7和3.5 一样访问
@staticmethod
和@classmethod
不需要的对象,只是SomeClass.also_not_reachable
(尽管它们需要独特的名称)。如果您需要从类方法访问它们,请使用self.also_not_reachable
*not_reachable
方法为not_as_easily_reachable_from_class_definition_as_a_lambda
xD
flake8
(flake8.pycqa.org)