Изменяемые и неизменяемые объекты в Python

Перевод статьи Mutable vs Immutable Objects in Python.

Все значения в Python это объекты. Объекты делятся на изменяемые и неизменяемые.

Python, схема объектов

Каждая переменная ссылается на экземпляр объекта. При создании, объекту присваивается уникальный идентификатор (object id) и тип объекта. Тип объекта не меняется после создания, но может изменится состояние объекта. Изменяемые объекты меняют своё состояние после создания, а неизменяемые сохраняются в том виде в котором были созданы.

Встроенные неизменяемые типы: int, float, bool, str, tuple, unicode. Встроенные изменяемые типы list, set, dict. Пользовательские классы обычно изменяемы. Для имитирования неизменяемости переопределите методы изменения и удаления значений чтобы они возвращали исключение.

Python. таблица изменяемых и неизменяемых объектов

Чтобы узнать ссылается ли переменная на изменяемый или неизменяемый рассмотрим подробнее функции id() и type().

Функции id и type

Встроенная функция id() возвращает числовой идентификатор объекта. Обычно это число соответствует месту нахождения объекта в памяти, однако это относится к особенностям реализации интерпретатора Python и зависит от платформы. Оператор is сравнивает идентификаторы двух объектов.

Встроенная функция type() возвращает тип объекта. Рассмотрим два примера.

Проверим, с помощью этих функций, какие типы являются изменяемыми, а какие нет.

Изменяемые и неизменяемые объекты

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

Мы создали объект типа int. Идентификаторы x и y ссылаются на один объект.

Выполним простую операцию:

Теперь

Ссылка находящаяся в переменной x изменилась. Изменилась именно ссылка, не сам объект, это показывает изменение идентификатора объекта. Объект 10 не изменился, переменная y продолжает ссылаться на него. Неизменяемые объекты не меняются после создания.

В случае изменяемых объектов

Мы создали объект типа list. Идентификаторы m и n ссылаются на один объект — список из трёх элементов неизменяемого типа int.

Изменим список, удалим один элемент:

Идентификатор объекта не меняется:

Переменные m и n так же ссылаются на один и тот же объект списка после изменения списка. Список теперь содержит два элемента [1, 2].

Особенности изменяемых и неизменяемых объектов:

  • Python обрабатывает изменяемые и неизменяемые объекты по-разному.
  • Доступ к неизменяемым объектам быстрее чем к неизменяемым.
  • Изменяемые объекты лучше использовать когда есть необходимость изменять размер или значение объекта после создания. Неизменяемые лучше применять когда объект останется всегда в том виде в котором был создан.
  • Неизменяемые объекты принципиально дороже в использовании когда их часто требуется "менять", так как любое изменение создаёт копию объекта.

Исключения в неизменяемости

В некоторых случаях неизменяемые объекты могут выглядеть как изменяемые.

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

Рассмотрим кортеж

Кортеж t содержит элементы разных типов. Первый элемент это неизменяемая строка, а второй изменяемый список. Кортеж неизменяемый и не содержит методов для изменения своего содержимого. То же самое относится к строке. Но список изменяемый и содержит методы для изменения своих значений. Содержимое неизменяемого кортежа не может быть изменено, но изменяемые объекты входящие в кортеж могут менять свои значения.

Как объекты передаются в функции

При передачи параметров в функции изменяемые объекты ведут себя аналогично тому что в других языках называется "передача по ссылке". Изменения объекта внутри функции отражаются на исходном объекте:

Неизменяемые объекты ведут себя так как будто происходит "передача по значению". Изменение объекта внутри функции не влияет на исходных объект:

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *