Расскажи про изменяемые и неизменяемые типы данных в Python

Ответ

В Python разделение на изменяемые (mutable) и неизменяемые (immutable) типы — это фундаментальная концепция, влияющая на поведение объектов, передачу аргументов в функции и управление памятью.

Неизменяемые типы (immutable): int, float, str, tuple, bool, frozenset, bytes.

  • После создания объект нельзя изменить. Любая операция, которая выглядит как изменение, на самом деле создает новый объект.
  • Это делает их потокобезопасными и предсказуемыми при использовании в качестве ключей словаря.
    a = "Hello"
    b = a          # `b` ссылается на тот же объект, что и `a`
    a += " World" # Создается НОВЫЙ строковый объект для `a`
    print(a)      # 'Hello World'
    print(b)      # 'Hello' (старый объект не изменился)

Изменяемые типы (mutable): list, dict, set, bytearray, пользовательские классы (по умолчанию).

  • Содержимое объекта можно изменить после создания, не создавая новый объект.
  • Требуют осторожности, особенно при передаче в функции или использовании значений по умолчанию.
    
    def append_to_list(item, target_list=[]):  # ОПАСНО: изменяемый аргумент по умолчанию!
    target_list.append(item)
    return target_list

Лучшая практика — использовать None

def append_to_list_safe(item, target_list=None): if target_list is None: target_list = [] target_list.append(item) return target_list


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

Ответ 18+ 🔞

А, слушай, вот эта тема с изменяемыми и неизменяемыми типами в Python — это, блядь, основа основ, но её так часто на раз-два проезжают, а потом люди охуевают от багов. Ёпта, давай разжую.

Представь, что у тебя есть два вида штук. Первые — как каменные скрижали, immutable. Написал a = "Привет" — и всё, высек в граните. int, float, строка, кортеж — они все такие. Попробуй изменить — нихуя не выйдет. Вместо этого Python, такой хитрая жопа, создаст тебе абсолютно новый кусок гранита, а старый так и будет лежать.

a = "Hello"
b = a          # `b` — это просто табличка, указывающая на тот же самый камень
a += " World" # БАЦ! Высекаем новый камень с новой надписью для `a`
print(a)      # 'Hello World' (новый камень)
print(b)      # 'Hello' (старый камень, на который всё ещё смотрит `b`, не тронут)

Вот это «создаётся новый объект» — это, ёбаный насос, ключевой момент. Поэтому их и безопасно использовать как ключи в словарях — они не поменяются у тебя под носом.

А теперь вторые — изменяемые, mutable. Это, сука, как пластилин или глина. list, dict, set. Слепил список — и потом можешь его мять, добавлять, удалять, и это всё тот же кусок глины в памяти.

И вот тут начинается пиздец, если не понимать. Самый классический косяк, про который легенды ходят — изменяемый аргумент по умолчанию.

def append_to_list(item, target_list=[]):  # ОПАСНОСТЬ, ЕБАНОЕ МАТЕРНОЕ СЛОВО!
    target_list.append(item)
    return target_list

Смотри, что происходит. Эта пустая скобка [] создаётся один раз, в момент определения функции. Не каждый раз при вызове! Один раз! И потом все вызовы без аргумента target_list будут тыкать в один и тот же список. Это пиздец как неочевидно.

print(append_to_list(1))  # [1]
print(append_to_list(2))  # А тут будет [1, 2], а не [2]! Сам от себя охуел?

Лучшая практика — делать через None. Просто запомни, как «Отче наш»:

def append_to_list_safe(item, target_list=None):
    if target_list is None:
        target_list = []  # А вот тут новый список создаётся КАЖДЫЙ РАЗ при вызове
    target_list.append(item)
    return target_list

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