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

На какие направления делятся типы данных в Python?

1.3 Junior🔥 171 комментариев
#Python Core

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

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

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

Классификация типов данных в Python

Типы данных в Python делятся на несколько направлений в зависимости от различных критериев классификации. Разберём основные подходы.

1. По изменяемости (Mutability)

Это одна из самых важных классификаций в Python.

Неизменяемые типы (Immutable)

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

# int, float, complex
x = 5
x = 10  # Создаётся новый объект, старый забывается

# str (строки)
text = "Hello"
text = text + " World"  # Новая строка, старая неизменна

# tuple (кортежи)
t = (1, 2, 3)
t = (1, 2, 3, 4)  # Новый кортеж

# frozenset (неизменяемое множество)
fs = frozenset([1, 2, 3])
fs = frozenset([1, 2, 3, 4])  # Новый frozenset

# bool
flag = True
flag = False  # Новое значение

# None
value = None
value = 42  # Новое значение

# bytes
b = b"hello"
b = b"world"  # Новая байт-строка

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

# Неизменяемые типы безопасны как ключи словаря
d = {}
t = (1, 2, 3)
d[t] = "value"  # OK

# Нельзя с изменяемыми типами
list_key = [1, 2, 3]
d[list_key] = "value"  # TypeError: unhashable type: 'list'

Изменяемые типы (Mutable)

Можно менять без создания нового объекта:

# list (списки)
my_list = [1, 2, 3]
my_list.append(4)      # Тот же объект, изменён
my_list[0] = 999       # Тот же объект, изменён

# dict (словари)
my_dict = {'a': 1}
my_dict['b'] = 2       # Тот же объект, изменён
del my_dict['a']       # Тот же объект, изменён

# set (множества)
my_set = {1, 2, 3}
my_set.add(4)          # Тот же объект, изменён
my_set.remove(1)       # Тот же объект, изменён

# bytearray (изменяемая байт-строка)
ba = bytearray(b"hello")
ba[0] = ord('H')       # Тот же объект, изменён

# Пользовательские классы (обычно изменяемы)
class User:
    def __init__(self, name):
        self.name = name

user = User("John")
user.name = "Jane"     # Тот же объект, изменён

Практический пример проблемы изменяемости:

# Опасно с изменяемыми параметрами по умолчанию
def add_item(item, lst=[]):  # ОПАСНО!
    lst.append(item)
    return lst

result1 = add_item(1)        # [1]
result2 = add_item(2)        # [1, 2] ← Неожиданно!

# Правильно:
def add_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

result1 = add_item(1)        # [1]
result2 = add_item(2)        # [2]

2. По скалярности (Scalarity)

Скалярные типы (Scalar)

Представляют одно значение:

# Числовые
int_val = 42
float_val = 3.14
complex_val = 1 + 2j

# Строки
str_val = "Hello"

# Логические
bool_val = True

# Пустое значение
none_val = None

# Байты
bytes_val = b"data"

Составные типы (Collection/Composite)

Содержат несколько значений:

# Упорядоченные (порядок важен)
list_val = [1, 2, 3]           # Изменяемый список
tuple_val = (1, 2, 3)          # Неизменяемый кортеж
str_val = "abc"                # Строка (последовательность символов)
range_val = range(1, 4)        # Диапазон чисел
deque_val = deque([1, 2, 3])   # Двусторонняя очередь

# Неупорядоченные (порядок не важен)
set_val = {1, 2, 3}            # Изменяемое множество (уникальные значения)
frozenset_val = frozenset({1, 2, 3})  # Неизменяемое множество

# Ассоциативные (ключ-значение)
dict_val = {'a': 1, 'b': 2}    # Словарь

3. По назначению (Purpose)

Числовые типы

int          # Целые числа: 42, -1, 0
float        # С плавающей точкой: 3.14, -2.5
complex      # Комплексные: 1+2j, 3j
decimal      # Высокая точность (из модуля decimal)

Текстовые типы

str          # Unicode строки: "Hello"
bytes        # Байт-строки: b"data"
bytearray    # Изменяемые байт-строки

Логические типы

bool         # Истина/Ложь: True, False
NoneType     # Пустое значение: None

Последовательные типы (Sequences)

str          # Последовательность символов
bytes        # Последовательность байт
list         # Последовательность элементов
tuple        # Неизменяемая последовательность
range        # Последовательность чисел
deque        # Двусторонняя последовательность

Множества (Sets)

set          # Изменяемое множество
frozenset    # Неизменяемое множество

Картирование (Mapping)

dict         # Словарь (наиболее распространённый)
defaultdict  # Словарь с значениями по умолчанию
OrderedDict  # Упорядоченный словарь (Python < 3.7)
Counter      # Счётчик элементов
ChainMap     # Несколько словарей как один

4. По способу хранения (Memory Layout)

Атомарные типы

# Хранятся как отдельное значение в памяти
int x = 5
float y = 3.14
bool z = True

Ссылочные типы (Reference Types)

# Переменная хранит ссылку (адрес) на объект в памяти
my_list = [1, 2, 3]           # Переменная → адрес в памяти → список
my_dict = {'a': 1}            # Переменная → адрес в памяти → словарь

# Поэтому присваивание не копирует:
list1 = [1, 2, 3]
list2 = list1                  # list2 указывает на тот же объект
list2.append(4)                # list1 тоже изменился! [1, 2, 3, 4]

# Нужна копия:
list3 = list1.copy()           # Неглубокая копия
list4 = copy.deepcopy(list1)   # Глубокая копия

5. По иерархии (Type Hierarchy)

object (всё является объектом)
├── type (метакласс)
├── int, float, complex (числа)
├── str, bytes (текст)
├── bool (логика)
├── NoneType
├── list, tuple (последовательности)
├── dict (картирование)
├── set, frozenset (множества)
├── range
├── function
├── class
└── Custom classes

Проверка типа:

type(42)                       # <class 'int'>
type(3.14)                     # <class 'float'>
type([1, 2, 3])               # <class 'list'>

# isinstance — более правильный способ
isinstance(42, int)            # True
isinstance([1, 2], (list, tuple))  # True
isinstance(42, (int, float))   # True

6. По сложности (Complexity)

Простые (Primitive)

int, float, bool, str, bytes, None

Составные (Container)

list, dict, set, tuple, frozenset

Специальные

function, class, generator, coroutine, module

7. По типизации в контексте Python

Динамически типизированные

# Тип определяется во время выполнения
x = 5          # int
x = "hello"    # str (теперь это string)
x = [1, 2]     # list (теперь это list)

# Никакой ошибки — Python позволяет

Статическое аннотирование (Type Hints)

# Python 3.5+: опциональные аннотации типов
def greet(name: str) -> str:
    return f"Hello, {name}!"

age: int = 25
users: list[dict[str, int]] = [
    {"name": "John", "age": 30},
    {"name": "Jane", "age": 25},
]

# Это не меняет поведение Python, только помощь для type checker
# Используй mypy для проверки:
# mypy script.py

Практическая таблица

ТипИзменяемыйУпорядоченныйУникальныеХешируемыйПример
int--42
str"Hello"
list[1, 2, 3]
tuple(1, 2, 3)
dict{'a': 1}
set{1, 2, 3}
frozensetfrozenset({1, 2})

Когда что использовать

# Нужна неизменяемость?
data = (1, 2, 3)           # tuple, не list
keys = frozenset([...])    # frozenset, не set

# Нужна быстрота поиска?
if item in my_set:         # set, не list (O(1) vs O(n))
    pass

# Нужен порядок + уникальные значения?
from collections import OrderedDict
orders = OrderedDict()     # В Python 3.7+ обычный dict сохраняет порядок

# Нужны высокие требования к точности?
from decimal import Decimal
price = Decimal('19.99')   # Не float для денег!

# Нужны динамические значения по умолчанию?
from collections import defaultdict
counts = defaultdict(int)  # Вместо dict + проверок

Вывод

Типы данных в Python классифицируются по нескольким направлениям:

  1. Изменяемость — неизменяемые (int, str, tuple) vs изменяемые (list, dict, set)
  2. Скалярность — скалярные (одно значение) vs составные (коллекции)
  3. Назначение — числовые, текстовые, логические, последовательные, множества, картирование
  4. Память — атомарные vs ссылочные
  5. Иерархия — по наследованию от object
  6. Сложность — примитивные vs составные
  7. Типизация — динамическая (по умолчанию) vs статическая (аннотации)

Ключевой навык: понимать различия и выбирать правильный тип для каждой задачи.