Python中`foo, bar = foo[bar] = [1,2,3], 2`语句执行逻辑求解释
Python链式多重赋值的执行逻辑解析
你对语句的拆解顺序完全错误,Python的多重+链式赋值遵循先计算所有右侧表达式,再从右到左完成赋值的规则,不是你想的先执行下标赋值再执行多重赋值。
正确执行步骤(结合你的输出场景)
假设执行这条语句前,foo已被定义为[1,2,3],bar已被定义为2(否则会直接报NameError),语句foo, bar = foo[bar] = [1,2,3], 2的执行流程是:
- 计算右侧表达式:先创建列表
L = [1,2,3],再和整数2组成元组T = (L, 2)。 - 执行右侧的下标赋值:将
T赋值给foo[bar](也就是foo[2]),此时原foo从[1,2,3]变为[1,2, T]。 - 执行左侧的多重赋值:将元组
T解包,把L赋值给foo,把2赋值给bar。
关于循环引用的解释
你的输出中foo显示为[1, 2, ([...], 2)],其中[...]代表循环引用,说明实际场景中右侧的列表不是新创建的[1,2,3],而是直接引用了foo本身(可能是你输入代码时的笔误,比如写成了foo, bar = foo[bar] = foo, 2)。这种情况下:
- 元组
T = (foo, 2),其中foo是原列表[1,2,3]。 - 执行
foo[2] = T后,foo变成[1,2, (foo, 2)]。 - 执行
foo, bar = T时,foo被赋值为自身(此时已经是包含T的列表),导致foo[2]中的第一个元素就是foo自己,形成循环引用,所以显示为[...]。
为什么你的拆解会报错
你把顺序拆成先执行foo[bar] = [1,2,3], 2再执行foo, bar = foo[bar],但此时foo和bar还未定义,自然会报NameError;而原语句能执行的前提是,执行前foo和bar已经存在,且Python会先计算好右侧所有值,再依次完成赋值。
内容的提问来源于stack exchange,提问作者1277120515
相关产品推荐
相关产品推荐

