5.02. Работа с типами
Работа с типами
Преобразование типов — процесс изменения типа объекта путём интерпретации его значения в контексте другого типа. В Python различают явное (принудительное) и неявное (автоматическое) приведение типов. Явные преобразования осуществляются с помощью встроенных конструкторов типов.
Основные функции преобразования:
- int(x) — преобразует x в целое число. При преобразовании строки она должна содержать корректное целочисленное представление (возможно с знаком). При преобразовании числа с плавающей точкой отбрасывается дробная часть (усечение к нулю, а не округление). Примеры:
int("42") → 42,int(3.9) → 3. - float(x) — преобразует x в число с плавающей точкой. Поддерживает строки с десятичной записью, экспоненциальной формой ("1e3"), а также inf, nan. Примеры:
float("3.14") → 3.14,float(5) → 5.0. - str(x) — возвращает строковое представление объекта. Вызывает метод
__str__()объекта. Для встроенных типов результат обычно человеко-читаем. Пример:str(123) → "123",str(True) → "True". - bool(x) — возвращает True или False в соответствии с логическим значением объекта. Следует помнить, что в Python большинство объектов имеют «истинное» значение, за исключением None, False, 0, 0.0, 0j, пустых коллекций и строк ("", [], ), и объектов с переопределенным
__bool__()или__len__(), возвращающим 0.
bool не является просто «обёрткой» вокруг 0/1. Это полноценный тип, наследуемый от int, где True == 1, False == 0, но это не означает эквивалентности семантики.
Несмотря на динамическую природу Python, в современной разработке активно применяются инструменты статической типизации. Они позволяют выявлять ошибки на этапе анализа кода, улучшать автодополнение в IDE и документировать сигнатуры функций.
Статическая типизация реализуется через аннотации типов (PEP 484) и сторонние анализаторы.
Аннотации типов добавляются с помощью синтаксиса:
def process_data(value: str) -> int:
return len(value)
Они не влияют на выполнение программы, но доступны через __annotations__ и используются анализаторами.
Инструменты статического анализа:
- mypy — один из первых и наиболее распространённых статических анализаторов. Проверяет соответствие аннотаций типов, включая сложные случаи: объединения (Union), опциональные типы (Optional), дженерики.
- pyright — анализатор от Microsoft, написанный на TypeScript, интегрирован в VS Code. Отличается высокой скоростью и хорошей поддержкой современных возможностей Python (например, LiteralString, TypeGuard).
- pyre — разработан Facebook (Meta), ориентирован на производительность при анализе больших проектов. Менее популярен, но эффективен в специфических средах.
- Pydantic — не является анализатором типов, но активно использует аннотации для валидации данных при создании моделей. Обеспечивает runtime-проверку типов на основе схем, что делает его мощным инструментом для API и конфигураций.
Cтатическая типизация в Python — опциональна и не заменяет тестирование. Она снижает вероятность определённых классов ошибок, но не гарантирует корректность логики.
Работа с числами
Числовые типы в Python включают int, float, complex и decimal.Decimal (из стандартного модуля decimal). Рассмотрим основные операции и особенности.
Арифметические операции:
+,-,*,/— обычное деление (всегда возвращает float)//— целочисленное деление (floor division)%— остаток от деления**— возведение в степень-x,+x— унарные операции
Из особенностей, можно отметить следующее -
- деление
/всегда возвращаетfloat, даже если операнды делятся нацело; - целочисленное деление
//округляет вниз (к меньшему целому), включая отрицательные числа:-7 // 2 = -4; - приоритет операций следует математическим правилам; для группировки используются скобки.
Округление.
Python предоставляет несколько способов округления:
- round(x) — стандартное округление к ближайшему чётному при равенстве расстояний (банковское округление). Пример: round(2.5) → 2, round(3.5) → 4.
- math.floor(x) — округление вниз.
- math.ceil(x) — округление вверх.
- math.trunc(x) — усечение дробной части (эквивалентно int(x) для положительных).
Модуль decimal.
Для задач, требующих точной арифметики (финансовые расчёты, измерения), рекомендуется использовать тип Decimal из модуля decimal. Он представляет числа в виде десятичных дробей, избегая ошибок двоичного округления (0.1 + 0.2 != 0.3 в float). Точность и режим округления настраиваются через контекст (getcontext()). Операции выполняются медленнее, чем с float, но обеспечивают предсказуемость.
from decimal import Decimal, getcontext
getcontext().prec = 6
result = Decimal('0.1') + Decimal('0.2') # → Decimal('0.3')
Не следует сравнивать float на равенство. Вместо этого используйте math.isclose().
Работа со строками
Строки в Python — неизменяемые последовательности Unicode-символов (тип str). Поддерживают широкий набор операций и методов.
Конкатенация и повторение. Конкатенация: s1 + s2, через оператор «+». Повторение: s * n (где n — целое). Не рекомендуется использовать + в цикле для сборки строк — из-за неизменяемости каждый раз создаётся новый объект. Вместо этого следует использовать ''.join(iterable).
Пример конкатенации:
s1 = "Текст"
s2 = " и ещё текст."
print(s1 + s2)
Результат: Текст и ещё текст.
Пример повторения:
s = "Текст"
print(s * 3)
Результат будет «ТекстТекстТекст».
Форматирование строк.
Существует несколько подходов:
- f-строки (PEP 498):
name = "Alice"
print(f"Hello, {name}!")
F-строка означает «formatted string». Синтаксис подразумевает добавление буквы f перед текстом. Он позволяет подставлять переменные через фигурные скобки - {имя_переменной}.
Поддерживают выражения, вызовы функций, форматирование (:.2f, !r и т.д.).
- Метод .format():
"Hello, {}!".format(name)
"Value: {value:.2f}".format(value=3.1415)
Здесь принцип похож на f-строки, но подразумевает более неудобный синтаксис - нужно расставить в текст фигурные скобки {}, а уже после текста добавить вызов метода format() и в параметрах передать переменную или значение переменной.
- % formatting:
"Hello, %s!" % name
% подразумевает подстановку значения с использованием особого форматирования:
- '%d', '%i', '%u' - десятичное число;
- '%o' - число в восьмеричной системе счисления;
- '%x' - число в шестнадцатеричной системе счисления (буквы в нижнем регистре);
- '%X' - число в шестнадцатеричной системе счисления (буквы в верхнем регистре);
- '%e' - число с плавающей точкой с экспонентой (экспонента в нижнем регистре);
- '%E' - число с плавающей точкой с экспонентой (экспонента в верхнем регистре);
- '%f', '%F' - число с плавающей точкой (обычный формат);
- '%g' - число с плавающей точкой. с экспонентой (экспонента в нижнем регистре), если она меньше, чем -4 или точности, иначе обычный формат;
- '%G' - число с плавающей точкой. с экспонентой (экспонента в верхнем регистре), если она меньше, чем -4 или точности, иначе обычный формат;
- '%c' - символ (строка из одного символа или число - код символа);
- '%s' - строка;
- '%%' - знак «%».
Учитывая «замудрённость» подходов, очевидно, что лучше использовать первый метод, f-строки.
Срезы (slicing).
Строки поддерживают доступ по индексу и срезы:
s[i]— символ по индексу (от 0 до len(s)-1, отрицательные индексы отсчитываются с конца).s[start:stop:step]— срез. Примеры:s[1:4]— символы с 1 по 3.s[::-1]— строка в обратном порядке.s[::2]— каждый второй символ.
s = "Текст"
print(s[1:4])
Результат будет «екс».
Срезы безопасны: выход за границы не вызывает исключения, возвращается пустая строка или максимально возможный фрагмент.
Основные методы строк:
s.upper(),s.lower()— изменение регистра.s.strip([chars])— удаление пробельных символов (или указанных) с концов.s.split(sep=None)— разбиение на список по разделителю.s.replace(old, new[, count])— замена подстроки.s.startswith(prefix),s.endswith(suffix)— проверка начала/конца.s.find(sub)— возвращает индекс первого вхождения или -1.s.index(sub)— аналогично find, но вызывает ValueError при отсутствии.s.isalpha(),s.isdigit(),s.isalnum()— проверка содержимого.
Все методы возвращают новую строку, так как строки неизменяемы.
Работа с булевыми значениями
Тип bool — подкласс int, содержащий два значения: True и False. Используется для логических выражений, условий и управления потоком выполнения.
Логические операторы
and— логическое И (возвращает последнее истинное или первое ложное значение).or— логическое ИЛИ (возвращает первое истинное или последнее ложное).not— логическое НЕ (возвращает True или False).
Операторы поддерживают ленивую (short-circuit) семантику: второе выражение вычисляется только при необходимости.
x = a and b # если a — False, b не вычисляется
Сравнения.
Операторы сравнения (==, !=, <, <=, >, >=) возвращают bool.
==проверяет равенство значений, is — идентичность объектов.- Сравнение разных типов возможно, но может давать неочевидные результаты (например,
1 == True— True, так как bool — подкласс int). - Избегайте сравнения float на равенство; используйте math.isclose().
Любой объект может быть интерпретирован в булевом контексте (в if, while, and/or). Пустые или нулевые значения считаются ложными, остальные — истинными.
Работа с датами и временем
Модуль datetime предоставляет средства для работы с датами, временем и интервалами. Основные типы:
datetime.datetime— комбинированный объект дата+время.datetime.date— только дата.datetime.time— только время.datetime.timedelta— разница между двумя моментами времени.datetime.timezone— информация о часовом поясе.
Создание объектов:
from datetime import datetime, date, timezone
now = datetime.now() # текущие дата и время
utc_now = datetime.now(timezone.utc)
specific = datetime(2025, 4, 5, 12, 30, 0)
today = date.today()
Форматирование и парсинг:
strftime(format)— форматирование в строку.strptime(string, format)— парсинг строки в объект.
dt = datetime(2025, 4, 5)
dt.strftime("%Y-%m-%d") # → "2025-04-05"
datetime.strptime("2025-04-05", "%Y-%m-%d")
strptime чувствителен к формату и выбрасывает ValueError при несоответствии.
Операции с временем:
timedelta позволяет прибавлять/вычитать интервалы:
from datetime import timedelta
tomorrow = now + timedelta(days=1)
Разницу между двумя datetime можно получить как timedelta.
Рекомендуется работать с UTC внутри системы и конвертировать в локальное время только на вывод. timezone.utc — константа для UTC.
Для сложных сценариев (летнее время, правила перехода) используется сторонняя библиотека pytz или встроенный zoneinfo (начиная с Python 3.9).