Задать вопрос
@vtaeke

Почему поверхностная копия не изменяет значение?

Есть задачка на Создание копии экземлпяра. И когда мы создаем поверхностную копию экземпляра х y=copy(x), то по идеи у нас должны меняться 2 значения name и nums. Но меняется только nums, код ниже. Не могу догнать этот момент почему так? Про полные списки понятно.
from copy import copy, deepcopy
class MyClass:
    def __init__(self, name, nums):
        self.name=name
        self.nums=nums
    def show(self):
        print("name ->", self.name)
        print("nums ->", self.nums)
x=MyClass("Python", [1,2,3])
print("Экземпляр х:")
x.show()
#копии - поверхностная, полная
y=copy(x)
z=deepcopy(x)
print("Экземпляр y:")
y.show()
print("Экземпляр z:")
z.show()

print("Поля экземпляра х изменяются")
x.name="Java"
x.nums[0]=0
print("Экземпляр x:")
x.show()
print("Экземпляр y:")
y.show()
print("Экземпляр z:")
z.show()


ответ такой
Экземпляр x:
name -> Java
nums -> [0, 2, 3]
Экземпляр y:
name -> Python  Должен же измениться???
nums -> [0, 2, 3]
Экземпляр z:
name -> Python
nums -> [1, 2, 3]
  • Вопрос задан
  • 49 просмотров
Подписаться 1 Простой 2 комментария
Пригласить эксперта
Ответы на вопрос 1
trapwalker
@trapwalker Куратор тега Python
Программист, энтузиаст
всё как и долно быть.
В С-подобных языках программирования переменная - это, как бы, ящичек с именем. Вы в ящичек можете положить значение, а при присвоении в ящик кладётся другое значение, а старое значение уже с этим ящиком не будет ассоциировано. Один ящик - одно значение.

В Питоне переменная - это как ярлычок с именем. При присвоении вы, как бы, вешаете ярлычок на объект:
x = [1,2,3]
y=x
И у вас теперь есть два ярлычка: x и y. Оба привязаны к одному и тому же объекту.
Если вы этот объект измените (отредактируете элемент), то не важно как вы к нему будете обращаться, по какому из имён.

Нужно различать что вы меняете: вы либо перевешиваете ярлычок с именем на друго объект, либо меняете что-то внутри объекта, к которому привязан ярлычок. Чувствуете разницу?

Представьте, что в вашем объекте (Заявка) два атрибута: Имя_клиента и Адрес_квартиры.
Вы копируете заявку поверхностно. Меняете имя в одной из копий, а во второй всё осталось как было. Делаете ремонт в квартире по указанному адресу. Само собой алрес в обеих копиях заявки один итот же и вы его не меняели. Вы меняели объект по этому адресу.

Теперь вы берете заявку и делаете её глубокое копирование:
Тут начинается проблема у аналогии, но это нам не помешает.
Вы меняете имя в копии и тут всё работает как в прошлом примере.
Но при создании глубокой копии создалась новая абсолютно такая же квартира но с новым адресом. В копии заявки адрес уже другой. Если вы сделаете ремонт в квартире по новому или старому адресу, то на другой квартире это не отразится.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы