ПрограммированиеPython Backend разработчик

Что такое мутабельность (mutable/immutable) объектов в Python? Как это влияет на работу функций и передачу параметров? Приведите примеры типичных ошибок.

Проходите собеседования с ИИ помощником Hintsage

Ответ.

Мутабельность определяет, можно ли изменить объект без смены его идентификатора (адреса в памяти):

  • Мутабельные объекты (например, list, dict, set) можно менять: добавлять элементы, изменять или удалять.
  • Иммутабельные объекты (например, int, str, tuple, frozenset) нельзя изменить после создания — любые "изменения" создают новый объект.

Влияние на функции:

  • Когда передаёте мутабельный объект в функцию — она может его изменить.
  • С иммутабельными объектами изменений не произойдёт, даже если их "заменить" внутри функции.

Пример:

def f(lst): lst.append(42) data = [] f(data) print(data) # [42] def f2(x): x += 1 n = 1 f2(n) print(n) # 1

Вопрос с подвохом.

"Что выведет следующий код?"

def foo(bar=[]): bar.append(1) return bar print(foo()) print(foo())

Ответ: Выведет:

[1]
[1, 1]

Потому что аргументы функции инициализируются один раз при определении, а не каждый вызов. Списки (и другие мутабельные объекты) в аргументах функции — популярная ловушка.

Примеры реальных ошибок из-за незнания тонкостей темы.


История

В REST API возвращали список через функцию с дефолтным параметром:

def get_default_items(items=[]): items.append('x') return items

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


История

В функции планировали "заменить" строку:

def replace_word(word): word.replace('a', 'b') word = 'data' replace_word(word) print(word) # Ожидали 'dbtb', получили 'data'

Методы str не меняют исходную строку, а возвращают новую, но значение возвращаемого результата проигнорировали.


История

Работая с вложенными структурами:

original = [[1, 2], [3, 4]] copy = original[:] copy[0][0] = -1 print(original) # [[-1, 2], [3, 4]]

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