CPython中两种强制提前绑定方法的差异及函数存储值位置问询
闭包与默认参数的存储差异
示例代码
def foo_a(): x = 1 fun = (lambda _x: lambda: print(_x))(x) x = 2 return fun def foo_b(): x = 1 fun = lambda _x=x: print(_x) x = 2 return fun fa = foo_a() fb = foo_b()
观察到的现象
执行以下代码后:
print(fa.__closure__) # (<cell at 0x0000025CED84BFD0: int object at 0x0000025CE9E36930>,) print(fb.__closure__) # None
fa的闭包中能捕获到_x变量,而fb的__closure__为None,那fb里的_x存在哪里?
答案
fb中的_x是作为lambda函数的默认参数值,存储在函数对象的__defaults__属性里。
具体解释
定义lambda _x=x:时,Python会在函数定义的瞬间计算并绑定当前x的值(也就是1)作为_x的默认参数。这个值直接存在lambda的默认参数集合中,不属于闭包捕获的外部变量——因为默认参数是在函数定义阶段就完成求值和存储的,后续修改x=2不会影响到已经绑定的默认值,所以__closure__返回None。
可以通过以下代码验证:
print(fb.__defaults__) # (1,)
这个元组的第一个元素就是_x的默认值,也就是当初提前绑定的1。
内容的提问来源于stack exchange,提问作者jodag
相关产品推荐
相关产品推荐

