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

Как еще называются неизменяемые типы данных в Python?

1.6 Junior🔥 81 комментариев
#Python Core

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

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

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

Как еще называются неизменяемые типы данных в Python?

Неизменяемые типы данных в Python называются Immutable Types или Hashable Types. На русском: неизменяемые типы или хешируемые типы.

Определение

Неизменяемый тип (Immutable Type) — это тип данных, значение которого не может быть изменено после создания. Любая попытка изменить вызывает ошибку или создаёт новый объект.

Основные неизменяемые типы в Python

# 1. Числа (int, float, complex)
x = 42
x = 43  # На самом деле создаётся НОВЫЙ объект
print(id(x))  # каждый раз новый id

# 2. Строки (str)
text = "Hello"
text[0] = "J"  # TypeError: 'str' object does not support item assignment
text = "Hello" + " World"  # создаёт новую строку

# 3. Кортежи (tuple)
t = (1, 2, 3)
t[0] = 10  # TypeError: 'tuple' object does not support item assignment

# 4. Frozen sets (frozenset)
fs = frozenset([1, 2, 3])
# fs.add(4)  # AttributeError

# 5. Bytes
b = b"hello"
# b[0] = 65  # TypeError

# 6. None
# None всегда одно и то же значение

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

# 1. Списки (list) — изменяемые
lst = [1, 2, 3]
lst[0] = 10  # Изменяем в месте
print(lst)  # [10, 2, 3]

# 2. Словари (dict) — изменяемые
d = {"a": 1, "b": 2}
d["a"] = 10  # Изменяем в месте

# 3. Множества (set) — изменяемые
s = {1, 2, 3}
s.add(4)  # Добавляем в месте

Чем отличаются: изменяемые vs неизменяемые

# НЕИЗМЕНЯЕМАЯ (str)
s1 = "hello"
s2 = s1
s1 = "world"  # создаёт новый объект
print(s2)  # "hello" — не повлияло!

# ИЗМЕНЯЕМАЯ (list)
lst1 = [1, 2, 3]
lst2 = lst1
lst1[0] = 99  # изменяет в месте
print(lst2)  # [99, 2, 3] — повлияло!

Это важно при работе с функциями:

def modify_immutable(s: str):
    s = s + " modified"
    return s

text = "hello"
result = modify_immutable(text)
print(text)    # "hello" — не изменилась
print(result)  # "hello modified"

def modify_mutable(lst: list):
    lst[0] = 999
    return lst

original = [1, 2, 3]
result = modify_mutable(original)
print(original)  # [999, 2, 3] — изменилась!
print(result)    # [999, 2, 3]

Hashable vs Non-Hashable

Hashable (хешируемые) — это объекты, которые можно использовать как ключи словаря или элементы множества. Обычно это синоним неизменяемых типов.

# Hashable (работает как ключ dict или элемент set)
dict_keys = {
    1: "int",
    "name": "str",
    (1, 2): "tuple",
    frozenset([1, 2]): "frozenset"
}

my_set = {1, "text", (1, 2), frozenset([3, 4])}

# Non-hashable (ошибка как ключ dict)
dict_bad = {
    [1, 2]: "list"  # TypeError: unhashable type: 'list'
}

my_set_bad = {1, "text", [1, 2]}  # TypeError: unhashable type: 'list'

Как проверить, hashable ли объект?

from collections.abc import Hashable

print(isinstance("hello", Hashable))       # True
print(isinstance((1, 2), Hashable))        # True
print(isinstance([1, 2], Hashable))        # False
print(isinstance({1, 2}, Hashable))        # False

# Или вызвать hash()
print(hash("hello"))       # 5233100571393351674
print(hash((1, 2)))        # 529344067295497451
print(hash([1, 2]))        # TypeError: unhashable type: 'list'

Особенный случай: tuple с изменяемыми элементами

# Tuple с неизменяемыми элементами — hashable
t1 = (1, "text", (2, 3))
print(hash(t1))  # работает
print({t1})      # можно в set

# Tuple с изменяемыми элементами — NOT hashable!
t2 = (1, "text", [2, 3])  # содержит list
print(hash(t2))  # TypeError: unhashable type: 'list'
print({t2})      # TypeError

Почему это важно?

# 1. Безопасность в многопоточности
import threading

immutable_string = "config_value"
# Две ниточки могут читать одновременно, не боясь конфликтов

mutable_list = [1, 2, 3]
# Две ниточки могут сломать друг другу данные!

# 2. Кеширование
from functools import lru_cache

@lru_cache(maxsize=128)
def expensive_function(items: tuple) -> int:
    # Работает! tuple hashable
    return sum(items)

# expensive_function([1, 2, 3])  # TypeError!

# 3. Словари и множества
user_cache = {}
# Ключи должны быть hashable
user_cache[(user_id, timestamp)] = data  # tuple — OK
user_cache[[user_id, timestamp]] = data  # list — ERROR

# 4. Копирование vs изменение
import copy

original = (1, 2, [3, 4])
shallow = copy.copy(original)
shallow[2][0] = 999  # изменили список внутри
print(original)  # (1, 2, [999, 4]) — повлияло!

deep = copy.deepcopy(original)
deep[2][0] = 999  # не повлияет на оригинал

Performance: неизменяемые быстрее

import timeit

# Создание строки (неизменяемая)
print(timeit.timeit('x = "hello"', number=1000000))

# Создание списка (изменяемая)
print(timeit.timeit('x = ["hello"]', number=1000000))

# Список медленнее из-за дополнительного управления памятью

# Поиск в неизменяемом (хеш-таблица)
print(timeit.timeit('"hello" in ("hello", "world", "test")', number=1000000))

# Поиск в изменяемом (линейный поиск)
print(timeit.timeit('["hello"] in [["hello"], ["world"], ["test"]]', number=1000000))

Best Practices

# 1. Используй неизменяемые типы по умолчанию
def config():
    return {  # dictionary
        "database": ("localhost", 5432),  # tuple для хоста/порта
        "allowed_hosts": frozenset(["localhost", "127.0.0.1"])  # frozenset
    }

# 2. Передавай tuple вместо list в функции
def process_numbers(*numbers: int) -> int:  # *args даёт tuple
    return sum(numbers)

# 3. Используй frozen dataclasses для конфигов
from dataclasses import dataclass

@dataclass(frozen=True)
class Config:
    debug: bool
    db_url: str
    max_connections: int

config = Config(debug=False, db_url="postgres://", max_connections=10)
# config.debug = True  # FrozenInstanceError

# 4. Используй NamedTuple для структурированных данных
from typing import NamedTuple

class Point(NamedTuple):
    x: int
    y: int

p = Point(10, 20)
print(hash(p))  # hashable!
my_dict = {p: "origin"}  # можно ключом

Резюме

ТерминЗначение
ImmutableНе может быть изменена после создания
HashableМожет быть ключом словаря или элементом множества
Неизменяемые типыstr, int, float, tuple, frozenset, bytes, None
Изменяемые типыlist, dict, set

В Python неизменяемость и хешируемость идут рука об руку. Неизменяемые объекты безопаснее для многопоточности и быстрее для кеширования.