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はオブジェクトにバインドされています(1, {'item': 'value'})

名前qはキューオブジェクトにバインドされています。

q.put(a)呼び出されると、名前がバインドされているオブジェクトは、名前aがバインドされているオブジェクトを「q挿入」するため、名前aq[0]は同じオブジェクトを参照します。したがって、そのオブジェクトを変更すると、両方aq[0]バインドされているオブジェクトが変更されます(同じオブジェクトにバインドされているため)。

第二に、タプルは不変ですが、それは変更できないという意味ではありません。「コンテナ」としては不変であり、それ自体は変更できませんが、変更可能なオブジェクトを含めることができるため、その内容は変更される可能性があります。

ここに非常に有用で明確な記事: https ://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-nether/

于 2017-03-12T13:03:24.250 に答える