lambda
和def
都创建相同类型的函数 - 它们具有相同的元数据和功能。它们的技术差异在于语法:
lambda
是一个产生函数的表达式。
def
是一个产生函数的语句。
这是决定它们如何使用的关键。其他明显的差异只是来自lambda
/def
可以捕获的信息。
>>> def def_func(): pass
>>> lambda_func = lambda: None
>>> type(def_func) == type(lambda_func)
True
用法:表达式 vs 语句
lambda
更灵活,因为表达式可以成为更多的语言结构的一部分。
sort(values, key=lambda x: abs(x))
相比之下,
def
更强大,因为它可以包含更多的语言结构。
def encode(num, base):
while num:
num, bit = divmod(num, base)
yield bit
这些差异直接源于它们分别是表达式和语句。Python没有特殊规则来决定在哪里可以使用 lambda
/def
。
无名的<lambda>
函数
认为 lambda
和 def
对应不同类型的函数的主要原因是 “元数据”: lambda
经常被称为 “匿名函数”,并且奇妙地总是产生一个 function <lambda>
。 其他特点包括 “lambda函数无法被 pickled”,最近typing也对 lambda
“不起作用”。
这是因为与 def
语法相比,lambda
语法没有办法指定名称、类型注释和类似内容。因此,Python 简单地为其填充合理的默认值:名称变成了 <lambda>
,注释留空。
>>> identity = lambda a: a
>>> identity.__qualname__
'<lambda>'
>>> identity.__annotations__
{}
自从
<lambda>
不是一个有效的标识符,使用这个元数据来查找函数的所有内容,尤其是
pickle
都会失败。
然而,这并不使该函数成为“匿名函数”类型。可以修补元数据以插入
def
提供的内容。
>>> identity.__qualname__ = identity.__name__ = 'identity'
>>> identity
<function __main__.identity(a)>
当然,在某一点上,可以直接使用
def
…