Вопрос-Ответ

Does Python make a copy of objects on assignment?

Создает ли Python копию объектов при присвоении?

Когда я пробую этот код:

dict_a = dict_b = dict_c = {}
dict_c['hello'] = 'goodbye'

print(dict_a)
print(dict_b)
print(dict_c)

Я ожидал, что он просто инициализирует dict_a, dict_b и dict_c словари, а затем назначит ключ в dict_c, в результате чего

{}
{}
{'hello': 'goodbye'}

Но, похоже, вместо этого у него эффект сквозного копирования:

{'hello': 'goodbye'}
{'hello': 'goodbye'}
{'hello': 'goodbye'}

Почему?

Переведено автоматически
Ответ 1

Это связано с тем, что в Python переменные (имена) являются просто ссылками на отдельные объекты. Когда вы присваиваете dict_a = dict_b, вы на самом деле копируете адрес памяти (или указатель, если хотите) из dict_b в dict_a. Все еще существует один экземпляр этого словаря.

Чтобы получить желаемое поведение, используйте либо dict.copy метод, либо use copy.deepcopy, если в вашем dict могут быть вложенные dicts или другие вложенные объекты.

>>> a = {1:2}
>>> b = a.copy()
>>> b
{1: 2}
>>> b[3] = 4
>>> a
{1: 2}
>>> b
{1: 2, 3: 4}
>>>
Ответ 2

Хотя

>>> dict_a, dict_b, dict_c = {}, {}, {}

это правильный путь в большинстве случаев, когда их становится больше 3, это выглядит странно

Представьте

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}

В случаях, когда я хочу инициализировать более 3 объектов, я использую

>>> a, b, c, d, e, f, = [dict() for x in range(6)]
Ответ 3

Ваше первое присваивание присваивает тот же объект словаря переменным dict_a, dict_b и dict_c. Это эквивалентно dict_c = {}; dict_b = dict_c; dict_a = dict_c .

Ответ 4

Как ранее говорил данбен, вы просто копируете один и тот же dict в 3 переменные, так что каждая из них ссылается на один и тот же объект.

Чтобы получить желаемое поведение, вы должны создать экземпляр другого dict в каждой переменной:

>>> dict_a, dict_b, dict_c = {}, {}, {}
>>> dict_c['hello'] = 'goodbye'
>>> print dict_a
{}
>>> print dict_b
{}
>>> print dict_c
{'hello': 'goodbye'}
>>>
2023-10-13 19:45 python