В КУРСЕ?

Разбираемся в теме

Два объекта Python делят один список: почему данные неожиданно смешались?

В объектно-ориентированном Python класс описывает общий способ устройства объектов, но не все его данные автоматически становятся отдельными для каждого экземпляра. Особенно заметна ошибка со списками: изменение через один объект внезапно видно через другой. Разберём два вымышленных плана подготовки выставки. Нам нужно, чтобы каждый план имел собственные пункты, а не общую случайно разделяемую очередь.

Атрибут класса может указывать на общий объект

Представим класс Plan, в теле которого создан пустой список points. Затем создаются экземпляры А и Б, а отдельных списков у них нет. При обращении к points они находят атрибут класса, указывающий на один и тот же список. Если через А добавить пункт подготовить зал, этот пункт будет виден и через Б. Это не самостоятельное копирование записи между планами. Оба обращения приводят к одному изменяемому объекту. Разные имена экземпляров не означают, что все достижимые через них данные тоже различаются.

Состояние экземпляра создают для каждого плана

Если по смыслу списки должны быть независимыми, при инициализации каждого экземпляра создают новый список и связывают его с атрибутом этого экземпляра. В обычном классе такое действие можно выполнить в методе __init__, используя self.points. Тогда создание А и создание Б выполняют отдельные операции создания списка. Добавление пункта в А не меняет список Б. При этом сам выбор зависит от задачи: общий справочник или действительно совместный список иногда нужен намеренно. Ошибка заключается не в существовании общих данных, а в несоответствии их устройства ожидаемому поведению.

Изменение объекта отличается от новой привязки имени

Добавление элемента в список меняет существующий объект. Присваивание нового списка атрибуту экземпляра может создать отдельную привязку, которая перекроет одноимённый атрибут класса для этого экземпляра. Эти действия не следует считать одинаковыми. Для понимания полезно рисовать ссылки: от экземпляра или класса к конкретному списку. Проверка одинакового содержимого тоже недостаточна. Два пустых списка могут быть разными объектами, а две ссылки могут вести к одному пустому списку. Именно общая принадлежность изменяемого объекта объясняет неожиданные изменения, а не внешнее совпадение значений.

Попробуйте на практике

Нарисуйте две модели хранения пунктов плана на бумаге. Установка Python не нужна; буквенные экземпляры и списки полностью вымышлены.

  1. В первой модели нарисуйте класс Plan с одним списком points и экземпляры А и Б, которые используют этот атрибут. Покажите, что оба обращения ведут к одному списку.
  2. Добавьте через А пункт подготовить зал. Запишите, что увидит Б, обращаясь к тому же списку.
  3. Во второй модели нарисуйте отдельный список для каждого экземпляра, создаваемый при его инициализации. Повторите добавление только в А.
  4. Сравните содержимое списков Б в двух моделях. Объясните различие через ссылки и создание объектов, а не через порядок букв.
  5. Добавьте проверку ожидания: после изменения А список Б должен оставаться пустым, если планы задуманы независимыми. Укажите, какая модель этому соответствует.

Как проверить результат. В первой модели оба плана видят добавленный пункт через общий список. Во второй список Б остаётся пустым. Вы различаете равенство содержимого и тождество объекта и можете объяснить, где создаётся независимое состояние.

Частые вопросы

Все атрибуты класса обязательно являются ошибкой?

Нет. Они подходят для данных, которые по замыслу общие для класса. Важно понимать, изменяем ли объект и должны ли экземпляры видеть одни и те же изменения. Архитектура следует смыслу задачи.

Достаточно ли дать экземплярам разные имена переменных?

Нет. Имя переменной обозначает ссылку на объект, но не гарантирует независимость вложенных данных. Нужно проверить, где создаются списки и какие ссылки на них сохраняются.

Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.

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

Зарегистрироваться
← К списку материалов