Ответ
Изменяемые (mutable) объекты в Python — это те, состояние которых можно изменить после создания без создания нового объекта. Это важно понимать для корректной работы с присваиванием, передачей в функции и использованием в качестве аргументов по умолчанию.
Основные встроенные изменяемые типы:
-
Список (list): Упорядоченная коллекция.
my_list = [1, 2, 3] my_list[0] = 100 # Изменение элемента по индексу my_list.append(4) # Добавление в конец my_list.extend([5, 6]) # Расширение списка my_list.sort() # Сортировка на месте print(my_list) # [1, 2, 3, 4, 5, 6]? Нет! [100, 2, 3, 4, 5, 6] -
Словарь (dict): Коллекция пар ключ-значение.
my_dict = {'name': 'Alice', 'age': 30} my_dict['age'] = 31 # Изменение значения my_dict['city'] = 'Berlin' # Добавление новой пары my_dict.update({'job': 'Engineer'}) value = my_dict.pop('name') # Удаление с возвратом значения print(my_dict) # {'age': 31, 'city': 'Berlin', 'job': 'Engineer'} -
Множество (set): Неупорядоченная коллекция уникальных элементов.
my_set = {1, 2, 3} my_set.add(4) # Добавление элемента my_set.remove(2) # Удаление элемента (KeyError если нет) my_set.discard(10) # Безопасное удаление (не вызывает ошибки) my_set.clear() # Очистка всего множества print(my_set) # set()
Важные следствия изменяемости:
-
Присваивание по ссылке: При присваивании
new_list = my_listсоздается не копия, а новая ссылка на тот же объект.original = [1, 2, 3] alias = original alias.append(4) print(original) # [1, 2, 3, 4] - изменился и оригинал!Решение: использовать копирование (
copy()для поверхностной копии,deepcopy()из модуляcopyдля вложенных структур). -
Аргументы по умолчанию в функциях: Изменяемый объект как аргумент по умолчанию создается один раз при определении функции.
def append_to(element, target=[]): # ОПАСНО: target создается один раз! target.append(element) return target print(append_to(1)) # [1] print(append_to(2)) # [1, 2] - сюрприз!Правильный паттерн:
def append_to(element, target=None): if target is None: target = [] # Новый список при каждом вызове без аргумента target.append(element) return target
К другим изменяемым типам относятся bytearray, array.array, объекты collections (например, deque, Counter), а также экземпляры пользовательских классов (по умолчанию).