为什么函数定义中的默认变量为1?

时间:2016-01-07 18:17:04

标签: python lambda

我发现了一个有趣的问题,为什么要尝试执行以下代码高尔夫挑战:

>>> f=lambda s,z=len(s): 5+z
>>> f("horse")
11                            #Expected 10
>>>              
>>> def g(s,z=len(s)):
...  print "z: ", z
...  print "sum: ", 5+z
...
>>> g("horse")
z:  6
sum:  11    
>>>                       
>>> len("horse") + 5           #Expected function operation
10 

双向创建函数似乎将z初始化为6而不是预期的5,为什么会这样?

3 个答案:

答案 0 :(得分:5)

python docs have a page that explains this

  

Python的默认参数在函数时被计算一次   定义,而不是每次调用函数

在您的情况下,s必须已经绑定到长度为6的字符串,然后才能创建lambda函数。当python使用z=len(s)评估lambda定义时,它会计算为z=6。每次调用该函数时都不会再次处理。

答案 1 :(得分:2)

除非已声明变量,否则不能在lambda表达式中使用赋值。在您的情况下,变量s之前已在此comment中声明,并且因为z在运行时绑定,因此使用s的值。

演示:

>>> a = 9
>>> f = lambda b: a + b
>>> f(3)
12
>>> a = 11
>>> f(3)
14
>>> f = lambda b, a=a: a + b # "a" gets bound to previous value 11
>>> f(3)
14
>>> a = 3 # 
>>> f(3)
14

正如您所看到的,如果在lambda表达式a=a中使用a,则值会在定义时绑定,并且更改该值不会对您的情况产生任何影响。

您应该像这样更改lambda表达式:

>>> f = lambda s: 5 + len(s)
>>> f('horse')
10

答案 2 :(得分:0)

您的函数定义不起作用,因为您定义了默认参数的方式。 Python的默认参数在定义函数时被计算一次,而不是每次调用函数时(比如Ruby)。这意味着如果你使用一个可变的默认参数并对其进行变异,那么你将为该函数的所有未来调用改变该对象。您的程序将无法正常工作,如下所示!

enter image description here