0
>>> import Queue
>>> q = Queue.PriorityQueue()
>>> a = (1, {'item': 'value'})
>>> q.put(a)
>>> q.queue
[(1, {'item': 'value'})]
>>> a[1]['count'] = 1
>>> q.queue
[(1, {'count': 1, 'item': 'value'})]
>>> q.get()
(1, {'count': 1, 'item': 'value'})

为什么添加后更改'a'的值时队列中的值会更改?元组本身是不可变的,但里面的字典是可变的。但我不明白为什么要更改队列?

4

2 回答 2

2

在 Python 中,对象是通过引用传递的。有些对象可能看起来是作为值传递的(例如字符串和整数),但那是因为这些对象是不可变的(例如,您不能更改整数对象的值1)。

因此,当您将字典放入队列时,将弹出另一端的实际字典而不是副本。

如果你想要一个副本,你可以使用字典的copy()方法,但请注意,它只会给你一个字典的浅副本:副本中的键和值将是相同的对象,它们本身可能是可变的。

于 2012-10-12T02:22:53.843 回答
1

在 Python 中,对象既不是“按引用”传递,也不是“按值”传递。

在您的示例中,名称a绑定到 object (1, {'item': 'value'})

该名称q绑定到队列对象。

q.put(a)被调用时,名称a绑定的对象被“放入”了名称q绑定的对象,从而名称aq[0]引用同一个对象。因此,当您修改该对象时,您正在修改 BOTHaq[0]绑定到的对象(因为它们绑定到同一个对象)。

其次,虽然元组是不可变的,但这并不意味着它不能改变。虽然作为一个“容器”,它是不可变的,自身不能改变,但它可以包含可变对象,因此它的内容可以改变。

此处非常有用且清晰的文章: https ://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/

于 2017-03-12T13:03:24.250 回答