lambda函数是不是python的保留字_Python:有和没有关键字参数的lambda函数行为?

我会尝试更深入地解释它.

如果你这样做

i = 0

f = lambda: i

你创建一个函数(lambda本质上是一个函数),它访问它的封闭范围的i变量.

在内部,它通过一个包含i的所谓闭包来实现.松散地说,它是一种指向真实变量的指针,它可以在不同的时间点保持不同的值.

def a():

# first, yield a function to access i

yield lambda: i

# now, set i to different values successively

for i in range(100): yield

g = a() # create generator

f = next(g) # get the function

f() # -> error as i is not set yet

next(g)

f() # -> 0

next(g)

f() # -> 1

# and so on

f.func_closure # -> an object stemming from the local scope of a()

f.func_closure[0].cell_contents # -> the current value of this variable

在这里,i的所有值 – 在它们的时间 – 存储在所述闭包中.如果函数f()需要它们.它从那里得到它们.

您可以在反汇编列表中看到差异:

这些函数a()和f()反汇编如下:

>>> dis.dis(a)

2 0 LOAD_CLOSURE 0 (i)

3 BUILD_TUPLE 1

6 LOAD_CONST 1 ( at 0xb72ea650, file "", line 2>)

9 MAKE_CLOSURE 0

12 YIELD_VALUE

13 POP_TOP

3 14 SETUP_LOOP 25 (to 42)

17 LOAD_GLOBAL 0 (range)

20 LOAD_CONST 2 (100)

23 CALL_FUNCTION 1

26 GET_ITER

>> 27 FOR_ITER 11 (to 41)

30 STORE_DEREF 0 (i)

33 LOAD_CONST 0 (None)

36 YIELD_VALUE

37 POP_TOP

38 JUMP_ABSOLUTE 27

>> 41 POP_BLOCK

>> 42 LOAD_CONST 0 (None)

45 RETURN_VALUE

>>> dis.dis(f)

2 0 LOAD_DEREF 0 (i)

3 RETURN_VALUE

将其与看起来像的函数b()进行比较

>>> def b():

... for i in range(100): yield

>>> dis.dis(b)

2 0 SETUP_LOOP 25 (to 28)

3 LOAD_GLOBAL 0 (range)

6 LOAD_CONST 1 (100)

9 CALL_FUNCTION 1

12 GET_ITER

>> 13 FOR_ITER 11 (to 27)

16 STORE_FAST 0 (i)

19 LOAD_CONST 0 (None)

22 YIELD_VALUE

23 POP_TOP

24 JUMP_ABSOLUTE 13

>> 27 POP_BLOCK

>> 28 LOAD_CONST 0 (None)

31 RETURN_VALUE

循环的主要区别是

>> 13 FOR_ITER 11 (to 27)

16 STORE_FAST 0 (i)

在b()与

>> 27 FOR_ITER 11 (to 41)

30 STORE_DEREF 0 (i)

在a()中:STORE_DEREF存储在单元格对象(闭包)中,而STORE_FAST使用“正常”变量,该变量(可能)的工作速度稍快一些.

lambda也有所不同:

>>> dis.dis(lambda: i)

1 0 LOAD_GLOBAL 0 (i)

3 RETURN_VALUE

这里有一个LOAD_GLOBAL,而上面的一个使用LOAD_DEREF.后者也是关闭的.

我完全忘记了lambda i = i:i.

如果您将值作为默认参数,它将通过完全不同的路径进入函数:i的当前值通过默认参数传递给刚刚创建的函数:

>>> i = 42

>>> f = lambda i=i: i

>>> dis.dis(f)

1 0 LOAD_FAST 0 (i)

3 RETURN_VALUE

这样函数被调用为f().它检测到缺少参数并使用默认值填充相应参数.所有这些都在调用函数之前发生;在函数中,您只需看到值并获取并返回.

还有另一种方法可以完成你的任务:只需使用lambda就好像它需要一个值:lambda i:i.如果你打电话给它,它会抱怨缺少一个参数.

但是你可以使用functools.partial来解决这个问题:

ff = [functools.partial(lambda i: i, x) for x in range(100)]

ff[12]()

ff[54]()

这个包装器获得一个可调用的和一些要传递的参数.生成的对象是一个可调用对象,它使用这些参数以及您为其提供的任何参数调用原始可调用对象.它可以在这里用来保持锁定到预期的值.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值