← Назад к вопросам

Что такое изменяемый объект в Python?

2.7 Senior🔥 281 комментариев
#Тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое изменяемый объект в Python?

Изменяемый объект (Mutable Object) в Python — это объект, содержимое которого можно изменять после его создания, не создавая новый объект. Это фундаментальное понятие в Python, которое влияет на поведение переменных, функций и структур данных.

Определение и суть

Когда говорят об изменяемости, речь идёт о возможности модифицировать содержимое объекта в памяти. При изменении изменяемого объекта его идентификатор (id) остаётся прежним:

# Список (list) - изменяемый объект
my_list = [1, 2, 3]
original_id = id(my_list)

# Изменяем содержимое
my_list.append(4)
my_list[0] = 100

# id не изменился - это тот же объект
print(id(my_list) == original_id)  # True

print(my_list)  # [100, 2, 3, 4]

Изменяемые типы данных в Python

1. Список (list)

# Списки полностью изменяемы
my_list = [1, 2, 3]

# Изменение элемента
my_list[0] = 10

# Добавление элемента
my_list.append(4)

# Удаление элемента
my_list.pop(1)

# Расширение
my_list.extend([5, 6])

print(my_list)  # [10, 3, 4, 5, 6]

2. Словарь (dict)

# Словари изменяемы
user = {
    'name': 'Иван',
    'age': 30,
    'email': 'ivan@example.com'
}

# Изменение значения
user['age'] = 31

# Добавление пары ключ-значение
user['city'] = 'Москва'

# Удаление ключа
del user['email']

# Обновление
user.update({'status': 'active'})

print(user)  # {'name': 'Иван', 'age': 31, 'city': 'Москва', 'status': 'active'}

3. Множество (set)

# Множества изменяемы
colors = {'red', 'green', 'blue'}

# Добавление элемента
colors.add('yellow')

# Удаление элемента
colors.remove('red')

# Обновление
colors.update(['orange', 'purple'])

print(colors)  # {'green', 'blue', 'yellow', 'orange', 'purple'}

Неизменяемые типы данных (для сравнения)

# Строка (str) - неизменяемая
text = 'Hello'
# text[0] = 'J'  # TypeError: 'str' object does not support item assignment

# Кортеж (tuple) - неизменяемая
coords = (10, 20)
# coords[0] = 15  # TypeError: 'tuple' object does not support item assignment

# Число (int, float) - неизменяемое
number = 42
# Невозможно "изменить" число, только переназначить переменную

Проблема с изменяемыми объектами: Aliasing

# Проблема 1: Несколько ссылок на один объект
list1 = [1, 2, 3]
list2 = list1  # list2 указывает на тот же объект!

list2.append(4)  # Изменяем через list2

print(list1)  # [1, 2, 3, 4] - list1 тоже изменился!
print(list2)  # [1, 2, 3, 4]
print(list1 is list2)  # True - это один и тот же объект

Решение: Копирование

# Решение 1: Поверхностное копирование (shallow copy)
list1 = [1, 2, 3]
list2 = list1.copy()  # или list(list1)

list2.append(4)

print(list1)  # [1, 2, 3] - не изменился
print(list2)  # [1, 2, 3, 4]

# Решение 2: Глубокое копирование (deep copy) для вложенных структур
import copy

nested_list = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(nested_list)

deep_copy[0].append(5)

print(nested_list)  # [[1, 2], [3, 4]] - не изменился
print(deep_copy)    # [[1, 2, 5], [3, 4]]

Проблема с изменяемыми аргументами функции

# Опасно: изменяемый объект как аргумент по умолчанию
def add_user(name, users=[]):  # ОПАСНО!
    users.append(name)
    return users

result1 = add_user('Иван')
print(result1)  # ['Иван']

result2 = add_user('Мария')
print(result2)  # ['Иван', 'Мария']  - данные накапливаются!

result3 = add_user('Петр')
print(result3)  # ['Иван', 'Мария', 'Петр']  - список растёт!

# Проблема: список users создаётся один раз при определении функции
# и переиспользуется при каждом вызове

Правильный подход

# Правильно: используем None как значение по умолчанию
def add_user(name, users=None):
    if users is None:
        users = []
    users.append(name)
    return users

result1 = add_user('Иван')
print(result1)  # ['Иван']

result2 = add_user('Мария')
print(result2)  # ['Мария']  - новый список!

result3 = add_user('Петр')
print(result3)  # ['Петр']  - новый список!

Изменяемость и функции

# Функция может неожиданно изменить входной объект
def modify_list(items):
    items.append(999)

my_data = [1, 2, 3]
modify_list(my_data)

print(my_data)  # [1, 2, 3, 999] - данные изменились!

# Это называется "побочный эффект" (side effect)
# Хороший код минимизирует побочные эффекты

Практические примеры

Пример 1: Работа со списком в цикле

# Изменение списка во время итерации - опасно
items = [1, 2, 3, 4, 5]

for item in items:
    if item == 3:
        items.remove(item)  # Может привести к неожиданному поведению

print(items)  # [1, 2, 4, 5] - но не всегда так работает

# Правильно: создать новый список
items = [1, 2, 3, 4, 5]
items = [item for item in items if item != 3]
print(items)  # [1, 2, 4, 5]

Пример 2: Кэширование изменяемых объектов

# Опасно: использовать изменяемый объект как ключ словаря
try:
    cache = {[1, 2, 3]: 'data'}  # TypeError!
except TypeError as e:
    print(e)  # unhashable type: 'list'

# Правильно: использовать неизменяемый объект
cache = {(1, 2, 3): 'data'}
print(cache[(1, 2, 3)])  # 'data'

Пример 3: Сравнение изменяемых объектов

# Сравнение по значению
list1 = [1, 2, 3]
list2 = [1, 2, 3]

print(list1 == list2)   # True (равны по значению)
print(list1 is list2)   # False (разные объекты в памяти)

# Изменяем один
list1.append(4)

print(list1 == list2)   # False (теперь не равны)
print(list1 is list2)   # False (всё ещё разные объекты)

Когда использовать изменяемые объекты

Используйте изменяемые объекты когда:

  • Нужна эффективность (изменение лучше, чем создание нового объекта)
  • Логика требует накопления данных
  • Нужна гибкость в структуре данных

Минимизируйте изменяемость когда:

  • Работаете с параллелизмом (многопоточностью)
  • Нужна предсказуемость и чистота функций
  • Работаете с кэшем или словарями

Таблица сравнения

ТипИзменяемостьМожет быть ключомПример
listДаНет[1, 2, 3]
dictДаНет{'a': 1}
setДаНет{1, 2, 3}
tupleНетДа(1, 2, 3)
strНетДа"hello"
int, floatНетДа42, 3.14

Понимание изменяемости — это ключ к написанию безопасного, предсказуемого и эффективного Python кода.