Основные типы данных языка Python и работа с переменными
Основной подход к определению типов переменных
Python использует динамическую типизацию: переменная не привязана к конкретному типу, а тип определяется значением, которое ей присвоено. Чтобы узнать тип переменной, применяется функция type(), а для проверки принадлежности к одному или нескольким типам - isinstance().
a = 10
print(type(a)) # <class 'int'>
a = "текст"
print(type(a)) # <class 'str'>
print(isinstance(a, str)) # TruePython задание переменных (задания на переменные в python)
Проблема: при выполнении операций с несовместимыми типами возникает TypeError. Например, сложение числа и строки:
x = 5
y = "10"
# print(x + y) # TypeError: unsupported operand type(s) for +: 'int' and 'str'типы переменных в python (типы переменных в python)
Возникающая ошибка: TypeError при попытке сложить число и строку. Решение: явно преобразовать один из операндов, например, print(x + int(y)) или print(str(x) + y), либо предварительно проверить типы с помощью isinstance().
Цель использования: правильное определение типов позволяет избежать ошибок выполнения и писать надёжный код, особенно при работе с данными из внешних источников.
Как явно указать тип переменной?
В Python можно использовать аннотации типов (type hints) для документирования ожидаемого типа. Однако они не проверяются во время выполнения и служат в первую очередь для статического анализа (например, в IDE).
age: int = 25
name: str = "Анна"
coordinates: tuple[float, float] = (55.75, 37.62)Проблема: аннотация не предотвращает присвоение значения другого типа. age = "двадцать пять" не вызовет ошибки. Решение: использовать mypy или другие инструменты статического анализа кода для проверки типов.
Цель: улучшение читаемости кода и помощь разработчикам в понимании ожидаемых данных.
Как преобразовать переменную в другой тип?
Для явного приведения типов используются встроенные функции: int(), float(), str(), list(), tuple(), set(), dict() и другие.
a = "123"
b = int(a) # 123
c = float("45.6") # 45.6
d = str(100) # "100"
e = list("abc") # ['a', 'b', 'c']
f = tuple([1, 2]) # (1, 2)Возникающая ошибка: ValueError при передаче строки с неподходящим содержимым (например, int("abc")). Решение: обрабатывать исключение с помощью try/except или предварительно проверять строку регулярным выражением.
Цель: обеспечить совместимость данных при вводе, сериализации или взаимодействии между разными модулями.
В чем разница между изменяемыми и неизменяемыми типами?
Неизменяемые (immutable) типы: int, float, str, bool, tuple, frozenset, bytes. Изменяемые (mutable): list, dict, set, bytearray. Изменяемые объекты можно модифицировать после создания, неизменяемые - нет.
# Неизменяемый: строка
s = "привет"
# s[0] = "П" # TypeError: 'str' object does not support item assignment
# Изменяемый: список
lst = [1, 2, 3]
lst[0] = 100 # теперь [100, 2, 3]
lst.append(4) # [100, 2, 3, 4]Проблема: попытка изменить неизменяемый объект вызывает TypeError. Решение: создать новый объект вместо изменения (например, для строки использовать срезы: s = "П" + s[1:] ).
Цель: понимание этого различия важно для выбора правильной структуры данных, оптимизации памяти (неизменяемые объекты могут быть хешированы и использованы как ключи словаря) и предотвращения побочных эффектов.
Как проверить принадлежность переменной к нескольким типам?
Функция isinstance() принимает кортеж типов и возвращает True, если переменная относится к одному из них.
value = 3.14
if isinstance(value, (int, float)):
print("Числовой тип")
# Вывод: Числовой типСравните с type(), который не поддерживает такую проверку без дополнительных условий.
Проблема: использование type(value) == int or type(value) == float избыточно и не учитывает наследование (например, bool является подклассом int). Решение: всегда предпочитать isinstance() для проверки типа.
Цель: универсальная и безопасная проверка типов, особенно при работе с иерархией классов.
Как использовать None для обозначения отсутствия значения?
Тип NoneType имеет единственное значение None, которое часто применяется как маркер отсутствия данных. Проверка выполняется через оператор is.
result = None
if result is None:
print("Результат не получен")Проблема: путаница None с ложными значениями (0, False, пустая строка). Проверка if not result будет ложной для всех этих случаев. Решение: использовать явную проверку if result is None.
Цель: явное обозначение отсутствия значения, распространено в возвращаемых значениях функций и при инициализации переменных.
Расширенные примеры работы с типами переменных
Распаковка кортежей и обмен значениями
# Обмен без временной переменной
a, b = 10, 20
a, b = b, a # a=20, b=10
print(a, b)
# Вывод: 20 10
# Распаковка с использованием звёздочки
first, *middle, last = [1, 2, 3, 4, 5]
print(first, middle, last)
# Вывод: 1 [2, 3, 4] 5Глубокое копирование изменяемых объектов
import copy
original = [[1, 2], [3, 4]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)
original[0][0] = 99
print(original) # [[99, 2], [3, 4]]
print(shallow) # [[99, 2], [3, 4]] - разделяют вложенные списки
print(deep) # [[1, 2], [3, 4]] - независимая копияАннотации типов с Union
from typing import Union
def process(value: Union[int, str]) -> str:
if isinstance(value, int):
return str(value * 2)
return value.upper()
print(process(5)) # "10"
print(process("hi")) # "HI"Преобразование списка в кортеж и обратно
lst = [1, 2, 3]
tpl = tuple(lst) # (1, 2, 3)
lst2 = list(tpl) # [1, 2, 3]
print(lst is lst2) # False - разные объектыРабота с байтовыми строками
# bytes - неизменяемый
b = bytes([100, 101, 102])
print(b) # b'def'
# bytearray - изменяемый
ba = bytearray(b)
ba[0] = 120
print(ba) # bytearray(b'xef')Комплексные числа и их атрибуты
z = 3 + 4j
print(z.real) # 3.0
print(z.imag) # 4.0
print(z.conjugate()) # (3-4j)
print(abs(z)) # 5.0 - модуль комплексного числаПроверка типа с помощью typing.get_type_hints
from typing import get_type_hints
def greet(name: str, age: int = 18) -> str:
return f"{name}, {age} лет"
hints = get_type_hints(greet)
print(hints)
# Вывод: {'name': <class 'str'>, 'age': <class 'int'>, 'return': <class 'str'>}