-
n=n 是什么意思?
lambda 允许您定义带参数的函数,就像def。这些参数可以有default argument values。所以,lambda n=n: 与 def foo(n=n): 相同。
事实上,当面对一个您无法阅读的复杂表达式时,通常值得将其分解为简单的语句:
list = []
for n in range(10):
def spam(n=n):
def eggs(x):
return x+n
return eggs
list.append(spam)
现在,为什么要创建一个名为 n 且默认值为 n 的参数?为什么不只是lambda:? The official FAQ 解释了这一点,但让我们试着总结一下。
如果你只是这样写:
funcs = [lambda: n for n in range(10)]
...你得到的是 10 个无参数函数,它们都是对同一个变量 n 的闭包。因为n在循环结束时的值为9,所以当被调用时,它们都将返回9。
但如果你这样做:
funcs = [lambda n=n: n for n in range(10)]
... 你得到的是一个可选参数n 的10 个函数(它从视图中隐藏了闭包n),其默认值是定义每个函数时n 的值。因此,当不带参数调用时,第一个将返回 0,第二个将返回 1,依此类推。
当然,在您的情况下,这些函数不仅仅是返回n,它们还返回一个接受参数、将n 添加到其中并返回结果的函数。但想法是一样的;您希望它们返回不同的函数,它们将 0、1、... 9 添加到它们的参数中,而不是所有返回的函数都添加 9。
-
list 的内容是什么?
list 将是一个可选参数的 10 个函数,其默认值范围从 0 到 9,每个函数返回一个参数的函数。返回的函数是对外部函数的 n 值的闭包。因此,当它被调用时,它会返回其参数 x,以及范围从 0 到 9 的 n 变量。
- 的输出是什么
print(list[0](14))
在这里,您使用参数 14 调用第一个外部函数 list[0]。因此,n 的默认值不是 0,而是 14。所以,您将得到的是一个函数,它接受一个参数并将 14 添加到它。但它会打印出如下内容:
<function <listcomp>.<lambda>.<locals>.<lambda> at 0x105f21f28>
Python 3.4+ 试图通过告诉你在哪里找到函数定义来提供帮助。 通常,当一个函数嵌套这么深时,沿途的大部分步骤都有名称。在这种情况下,你有三层匿名函数,所以没有一个名字很有用……
为了看到它做任何有用的事情,你必须调用它:
print(list[0](14)(20))
这会给你34。
您也可以使用inspect 模块,或者只是dir,在函数内部进行探索。例如,print(list[0](14).__code__.co_freevars[0], list[0](14).__closure__[0].cell_contents) 会告诉您它已将数字 14 隐藏在名称 n 下,供其内部函数使用。
…
print(list[0]()(14))
在这里,您再次调用list[0],但这次没有参数,所以它的n 获得0 的默认值。因此,它返回一个将0 添加到其参数的函数。然后用14 调用该函数,得到14。