Главная / Курсы / Python / Классификация типов данных, создание объектов
# Глава 8. Классификация типов данных, создание объектов > Всегда начинайте со структуры данных. Джон Кармак Рассмотрим структуры данных, встроенные в интерпретатор. Если однажды вы встанете перед дилеммой, применить ли встроенный в язык тип или пользовательский класс, то помните: в недрах интерпретатора CPython все встроенные типы — это оптимизированные структуры на языке C. Как следствие, они выигрывают по эффективности у пользовательских классов. ## Какие бывают типы данных В питоне есть три категории типов: - **Встроенные типы.** Для их использования не требуются дополнительные манипуляции вроде подключения модулей. Эти типы вшиты в интерпретатор. Например, целочисленный тип `int`. - **Библиотечные типы,** доступные после импорта стандартных модулей языка. Эти типы — неотъемлемая часть питона, но для их использования требуется подключение модуля через ключевое слово `import`. К таким типам например относится `socket`, реализованный в одноименном модуле. - **Пользовательские типы:** это любые классы из third-party модулей, которые устанавливаются менеджером пакетов, а также самописные классы из вашего кода. Например, `array` в библиотеке `numpy` для математических расчетов. Встроенные типы предусмотрены для: - Числовых значений (numerics). - Последовательностей (sequences). - Множеств (sets). - Отображений ключ-значение (mappings). - Прочих абстракций вроде файлов и исключений. С этим знанием мы разберем, на какие категории делятся встроенные типы. ## Изменяемые и не изменяемые типы {#block-mutable-immutable-types} Самое важное, что нужно помнить про встроенные типы: они делятся на изменяемые (mutable) и неизменяемые (immutable). Любая сущность в питоне является объектом. Целое число — это объект, функция — это объект, исключение — объект... Любая переменная — это объект, то есть экземпляр конкретного класса. Когда объект инстанцируется, интерпретатор присваивает ему тип и уникальное число — id объекта. Эта судьба уготована даже целым числам и булевым флагам. Так вот, какие-то объекты в питоне могут менять свое состояние после инстанцирования и поэтому называются изменяемыми. А какие-то — не могут. **Неизменяемые** встроенные типы: - `int` — целое число, - `float` — число с плавающей точкой, - `complex` — комплексное число, - `bool` — логическое значение, - `NoneType` — тип для единственного объекта-синглтона: неопределенного значения `None`, - `str` — строка, - `tuple` — кортеж, - `range` — неизменяемая последовательность чисел, - `frozenset` — неизменяемое множество, - `bytes` — неизменяемая последовательность байтов. **Изменяемые** встроенные типы: - `list` — список, - `set` — множество, - `dict`— словарь. - `bytearray` — изменяемая последовательность байтов. - `memoryview` — «окно» на некую область в памяти, через которое ее можно читать и модифицировать. Тип `memoryview` умеет работать с двумя встроенными типами: `bytes` и `bytearray`. Обратите внимание, `int` и `str` — неизменяемые! Так что же, над ними нельзя проводить операций вроде инкремента и конкатенации? Можно, но под капотом интерпретатора это будет означать замену одного объекта на другой объект этого же типа с новым id. Чтобы это доказать, воспользуемся двумя встроенными функциями: `id()` и `type()`. Функция `id()` возвращает идентификатор объекта: ```python {.example_for_playground} lang = "ru" print(id(lang)) ``` Этот код выведет произвольное целое число — id строкового объекта `lang`. Разумеется, от запуска к запуску число будет меняться. Например, вывод этого кода может выглядеть так: ```python 139799602438576 ``` `type()` возвращает название класса (типа) объекта: ```python {.example_for_playground} is_connected = True print(type(is_connected)) ``` Результат вывода этого кода в консоль будет таким: ```python <class 'bool'> ``` Проведите эксперимент. Заведите переменную `count`, равную 5. Выведете в консоль ее тип. На следующей строчке выведите ее id. Затем инкрементируйте переменную на 1. {.task_text} Инкремент — это оператор `+= n`, где `n` — целое число. {.task_text} После инкремента вновь выведите id переменной. Визуально убедитесь, что id переменной `count` до инкремента и после инкремента не совпадают. {.task_text} ```python {.task_source #python_chapter_0080_task_0010} ``` Для получения типа переменной воспользуйтесь функцией `type()`. Для получения id переменной воспользуйтесь функцией `id()`. Инкремент переменной выглядит так: `count += 1`. {.task_hint} ```python {.task_answer} count = 5 print(type(count)) print(id(count)) count += 1 print(id(count)) ``` Как видите, эксперимент подтвердил тот факт, что `int` — неизменяемый тип. После каждой модификации переменной она неявным образом заменяется на новую. Мы будем часто касаться изменяемости и неизменяемости встроенных типов, а пока перейдем к другой их классификации: на скаляры и коллекции. ## Скалярные типы и коллекции Встроенные типы данных делятся на две категории: - Скалярные (их еще называют простые, неделимые). - Коллекции (составные, структурированные). Все **скалярные типы** в питоне неизменяемые. К ним относятся: - Числа. - `int`. Целое число: -98, 0, 9361 и так далее. - `float`. Число с плавающей точкой: 3, 1e-7, 45.03455, -e5. - `complex`. Комплексное число: `-5.6 + 2j`. - `bool`. Логическое значение (флаг): `True` и `False`. - `NoneType`. Неопределенное значение переменной: `None`. **Коллекции** представлены типами: - [Строка:](/courses/python/chapters/python_chapter_0100/) `str`, последовательность Unicode символов. - [Список:](/courses/python/chapters/python_chapter_0110/) `list`, по сути массив. - [Кортеж:](/courses/python/chapters/python_chapter_0120/) `tuple`, его можно назвать неизменяемым списком. - [Множество:](/courses/python/chapters/python_chapter_0140#block-sets) `set`, набор уникальных значений. - [Неизменяемое множество:](/courses/python/chapters/python_chapter_0140#block-frozensets) `frozenset`. - [Словарь:](/courses/python/chapters/python_chapter_0150/) `dict`, контейнер пар ключ-значение. - [Диапазон:](/courses/python/chapters/python_chapter_0130/) `range`, неизменяемая последовательность чисел. - Последовательности бинарных значений: `bytes`, `bytearray`, `memoryview`. ## Создание объектов Объекты в питоне создаются двумя способами. **Способ первый:** просто присвоить объекту какое-то значение. Интерпретатор при этом сам выведет и присвоит наиболее подходящий тип. Вот как это выглядит на примере объявления логической переменной: ```python x = False ``` **Способ второй:** вызвать конструктор, имя которого совпадает с именем желаемого типа. Конструктор может инициализировать объект значением по умолчанию либо переданным в него значением, а также привести аргумент к требуемому типу. Инициализация логической переменной значением по умолчанию: ```python x = bool() ``` Приведение значения с плавающей точкой к логическому значению: ```python x = bool(9.9) ``` Второй способ применяется для приведения строки к числу, превращения значения с плавающей точкой в целое и прочих преобразований между типами: ```python x = int(3.14) ``` Корректно присвойте целочисленной переменной `max_val` значение, вызвав конструктор с аргументом-строкой "255". {.task_text} ```python {.task_source #python_chapter_0080_task_0020} ``` В конструктор `int()` требуется передать строку `"255"`. Возвращаемый конструктором объект требуется присвоить переменной `max_val`. {.task_hint} ```python {.task_answer} max_val = int("255") ``` ## Резюмируем - Все типы данных в питоне относятся ко встроенным, библиотечным либо пользовательским. - Встроенные типы делятся на скалярные и коллекции. - Встроенные типы делятся на изменяемые и не изменяемые. Все скалярные типы — неизменяемые. - Скалярные типы — это `int`, `float`, `complex`, `bool`, `NoneType`. - Есть два способа создания объектов: через обычное присваивание (например, `a = 8`) и через вызов конструктора (например, `b = float(a)`).
Отправка...
Наша группа в telegram. Здесь можно задавать вопросы и общаться.
Задонатить. Если вам нравится курс, вы можете поддержать развитие площадки!