Что такое mutable и immutable объекты?

Краткий ответ (для собеседования): mutable‑объекты (изменяемые) можно менять «на лету» после создания: их внутреннее состояние изменяется, при этом сам объект остаётся тем же. К таким типам относятся, например, list, dict, set. Immutable‑объекты (неизменяемые) нельзя изменить после создания: любая «изменяющая» операция создаёт новый объект. К таким типам относятся int, float, bool, str, tuple, frozenset.

Подробный ответ

Развернутое объяснение

Immutable (неизменяемый) объект — после создания его значение поменять нельзя; можно только создать новый объект и переназначить ссылку.

Mutable (изменяемый) объект — его состояние можно изменять без создания нового объекта: добавлять/удалять элементы, менять содержимое.

В Python всё — объект, у каждого есть тип, идентичность (адрес в памяти) и значение; именно тип решает, допускает ли он изменения значения.

К встроенным неизменяемым типам (immutable) относятся:

  1. числа: int, float, complex, bool;

  2. строки: str;

  3. кортежи: tuple;

  4. неизменяемые множества: frozenset.

Пример со строкой:

s = "hi"
t = s
s += "!"
# здесь s уже ссылается на НОВУЮ строку "hi!"
# t по‑прежнему ссылается на "hi"

Строка не меняется «внутри»: операция создаёт новый объект, а переменная переназначается на него.

К изменяемым (mutable) встроенным типам относятся:

  1. списки: list;

  2. словари: dict;

  3. множества: set;

  4. многие пользовательские классы.

Пример со списком:

items = [1, 2, 3]
other = items
items.append(4)
# и items, и other теперь указывают на один и тот же список [1, 2, 3, 4]

Мы не создавали новый список, а изменили существующий; все ссылки на него видят изменения.

Почему это важно для поведения кода?

Совместное использование объектов.

Для mutable: если две переменные указывают на один и тот же объект и вы его меняете, изменения видны через обе переменные. Для immutable: переназначение одной переменной не влияет на другие — создаётся новый объект, старый остаётся как есть.

Аргументы функций.

Если передать в функцию mutable‑объект (например, список) и изменить его внутри, изменения будут видны снаружи. Если передать immutable‑объект (например, число) и «изменить» его внутри, на самом деле вы создадите новый объект, и внешняя переменная не изменится. Пример:

def add_item(lst):
   lst.append(1)
   
data = []
add_item(data)

# data == [1]  — список изменили в функции

def add_one(x):
   x += 1
   
n = 10
add_one(n)

# n по-прежнему 10 — число не изменилось

Ошибки с параметрами по умолчанию

Из‑за изменяемости списков и словарей их опасно использовать как значения по умолчанию: список живёт между вызовами и накапливает данные. Это классический вопрос собеседований, и он напрямую связан с mutable‑поведением.

Читать полную статью в блоге