两者都lambda
创建def
相同类型的功能——它们具有相同类型的元数据和功能。它们的技术区别在于语法:
- A
lambda
是产生函数的表达式。
- A
def
是产生函数的语句。
这就是决定如何使用它们的一切。其他明显的差异仅来自信息lambda
/def
可以捕获。
>>> def def_func(): pass
>>> lambda_func = lambda: None
>>> type(def_func) == type(lambda_func)
True
用法:表达式与语句
Alambda
更灵活,因为表达式可以是更多语言结构的一部分。
# v--------------v arguments must be expressions
sort(values, key=lambda x: abs(x))
相比之下,adef
更强大,因为它可以包含更多的语言结构。
def encode(num, base):
while num: # statements must be inside statements
num, bit = divmod(num, base)
yield bit
这些差异直接源于一个是表达式,另一个是语句。Python 没有特殊的规则来决定lambda
/def
可以在哪里使用。
野性<lambda>
生长的地方
lambda
假设和def
对应不同类型函数的主要原因是元数据:lambda
通常被称为“匿名函数”,而且奇迹般地它总是产生一个function <lambda>
. 其他怪癖包括“无法腌制 lambda 函数”,最近键入也对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
……</p>