来自赋值语句文档:
一个赋值语句会首先计算表达式列表(请记住,这可以是单个表达式或逗号分隔的列表,后者产生一个元组),然后将单个的结果对象分别赋值给目标列表,从左到右。
你有两个赋值目标列表;a, b
和a[b]
,值为{}, 5
的元组被分别从左到右分配给这两个目标。
首先将{}, 5
元组解包到a, b
。现在你有a = {}
和b = 5
。注意{}
是可变的。
接下来,将同样的字典和整数分配给a[b]
,其中a
求值为字典,而b
求值为5
,因此你正在将键5
设置为元组({}, 5)
,从而创建循环引用。因此,{...}
指向与a
已经引用的相同对象。
由于赋值按从左到右的顺序进行,因此您可以将其分解为:
a, b = {}, 5
a[b] = a, b
因此,a[b][0]
与a
是相同的对象:
>>> a, b = {}, 5
>>> a[b] = a, b
>>> a
{5: ({...}, 5)}
>>> a[b][0] is a
True
NameError
,而a[b] = a, b = {}, 5
则能够工作。 - Claudiu{}, 5
被评估两次?为什么会这样呢?{}
仍然是同一个对象。这相当于d = {}; a, b = d, 5; a[b] = d, 5
。 - Martijn Pieterstmp0,tmp1 = {},5; a,b = tmp0,tmp1; a [b] = tmp0,tmp1
,这样就不会有循环引用了。 - nalzok