Примеры идут от простого к сложному: сначала динамическая типизация и обзор всех примитивных типов, затем строковые операции, кавычки и экранирование, и в конце — типичная ошибка склейки типов и современная проверка isinstance(). Весь вывод в комментариях получен запуском кода.
Пример 1. Тип принадлежит объекту, а не имени переменной
Присваивание не «объявляет тип» — оно связывает имя с уже готовым объектом. Одно и то же имя может по очереди указывать на объекты разных типов, это и называется динамической типизацией.
# dynamic_typing.py
value = 10
print(type(value)) # <class 'int'>
value = "ten"
print(type(value)) # <class 'str'>
value = 3.14
print(type(value)) # <class 'float'>
Что происходит: Python не проверяет тип заранее — он смотрит на объект в момент присваивания. Три вызова type(value) дают три разных ответа, хотя имя переменной не менялось.
Пример 2. Пять примитивных типов одним циклом
Лекция вводит int, float, str, bool и NoneType по отдельности. Полезно увидеть их рядом — так виднее общее правило: type() работает одинаково для любого объекта.
# primitive_types.py
samples = [5, -3, 0, 3.14, -5.2, "текст", True, False, None]
for item in samples:
print(repr(item), "->", type(item).__name__)
# 5 -> int
# -3 -> int
# 0 -> int
# 3.14 -> float
# -5.2 -> float
# 'текст' -> str
# True -> bool
# False -> bool
# None -> NoneType
Что происходит: bool — не просто «похожий на строку» ответ да/нет, а отдельный тип со своими True/False без кавычек. __name__ у типа даёт короткое имя без обёртки <class '...'>.
Пример 3. print() выполняет действие и возвращает None
# print_returns_none.py
result = print("Привет, мир!")
print(result)
print(type(result))
# Привет, мир!
# None
# <class 'NoneType'>
Что происходит: в конспекте это называют «процедурой» — функцией, которая выполняет действие (печатает текст на экран), а не возвращает значение для дальнейших вычислений. У print() нет отдельного «результата», кроме None.
Пример 4. Конкатенация, умножение строк и склейка с числом
+ для строк не добавляет пробел сам — его нужно вставлять явно. * повторяет строку, это удобно для разделителей. А вот склеить строку с числом через + напрямую нельзя — только через str() или f-string.
# concat_and_repeat.py
first_word = "Привет"
second_word = "мир"
print(first_word + second_word) # Приветмир
print(first_word + " " + second_word) # Привет мир
separator = "=" * 30
print(separator) # ==============================
price = 100
try:
print("Цена: " + price)
except TypeError as error:
print("TypeError:", error)
# can only concatenate str (not "int") to str
print("Цена: " + str(price)) # Цена: 100
print(f"Цена: {price}") # Цена: 100
Что происходит: ошибка возникает потому, что + для строк ожидает строку с обеих сторон. str(price) явно превращает число в текст; f-строка делает то же самое неявно и обычно читается лучше — про сам синтаксис f-строк подробнее в уроке 22 «Форматирование строк».
Пример 5. Четыре способа записать строку
Кавычки выбираются не по вкусу, а по тому, что внутри текста: если в тексте есть один вид кавычек, строку удобно обрамить другим видом, чтобы не экранировать.
# quotes.py
s1 = 'Одинарные кавычки'
s2 = "Двойные кавычки"
s3 = '''Тройные
одинарные'''
s4 = """Тройные
двойные"""
print(s1)
print(s2)
print(s3)
print(s4)
quote1 = "Она сказала: 'Привет!'"
quote2 = 'Он ответил: "Привет!"'
print(quote1) # Она сказала: 'Привет!'
print(quote2) # Он ответил: "Привет!"
Что происходит: тройные кавычки (одинарные или двойные — разницы нет) сохраняют переносы строк буквально и чаще всего используются для многострочного текста и docstring-комментариев к функциям.
Пример 6. Экранирование и «сырые» строки
\ запускает escape-последовательность: следующий символ читается специально, а не буквально. Если нужен буквальный обратный слэш (например, в пути Windows), либо удваивают его, либо используют «сырую» строку с префиксом r.
# escape_and_raw.py
print("Первая строка\nВторая строка")
print("Колонка1\tКолонка2")
print("Она сказала: \"Привет!\"")
print('Это \'пример\' экранирования')
path = "C:\\Users\\Student\\Documents"
raw_path = r"C:\Users\Student\Documents"
print(path) # C:\Users\Student\Documents
print(raw_path) # C:\Users\Student\Documents
print(path == raw_path) # True — результат один и тот же
r"...") не входят в конспект урока — это дополнение курса, распространённое в реальном коде для путей и регулярных выражений. Сверьтесь с String and Bytes literals.
Пример 7. sep и end на практике
По умолчанию print() разделяет аргументы пробелом (sep=" ") и завершает строку переносом (end="\n"). Оба параметра можно заменить на что угодно, включая пустую строку.
# sep_end.py
print(1, 2, 3, 4, 5, sep="---") # 1---2---3---4---5
print("Привет,", "мир", end="!\n") # Привет, мир!
print("a", "b", "c", sep="", end="|END\n") # abc|END
for i in range(3):
print(i, end=" ")
print()
# 0 1 2
Что происходит: в последнем блоке end=" " держит все числа на одной строке; финальный пустой print() добавляет перенос, которого не хватило после цикла.
Пример 8. input() всегда возвращает str — приведение типов
Даже если пользователь вводит число, input() отдаёт строку. Чтобы посчитать с этим значением, его нужно явно преобразовать: int(), float() или обратно str().
# type_conversion.py
raw_age = "25" # представим, что это результат input("Возраст: ")
print(type(raw_age)) # <class 'str'>
age = int(raw_age)
print(type(age), age + 1) # <class 'int'> 26
price = float("19.99")
print(price * 2) # 39.98
print(str(42) + " штук") # 42 штук
print(bool("False"), bool(""), bool("0")) # True False True
Что происходит: bool("False") — истина, потому что это непустая строка; булеву логику по значениям подробно разбирает урок 06.
Пример 9. Типичная ошибка и три способа её избежать
Склейка str + int — самая частая ошибка новичков на этой теме. Три рабочих варианта: печать через запятую, str() или f-строка.
# fix_typeerror.py
count = 3
try:
print("Осталось: " + count)
except TypeError as error:
print("TypeError:", error)
# can only concatenate str (not "int") to str
print("Осталось:", count) # запятая сама подставит пробел
print("Осталось: " + str(count)) # явное приведение
print(f"Осталось: {count}") # f-строка, современный стиль
print() — самый быстрый вариант для отладочного вывода. F-строка — стандарт для «боевого» текста, особенно если значений несколько. str() + + нужен реже — например, когда строка уже собирается по кускам в переменной.
Пример 10. type() vs isinstance() — современная проверка типа
Лекция использует type() для показа типа. На практике для проверки типа обычно используют isinstance() — он остаётся верным и для унаследованных классов, а type() == нет.
# isinstance_vs_type.py
x = True
print(type(x) == bool) # True
print(type(x) == int) # False — хотя bool является подклассом int
print(isinstance(x, bool)) # True
print(isinstance(x, int)) # True — bool это и есть int с двумя значениями
class Number(int):
pass
n = Number(5)
print(type(n) == int) # False — тип объекта именно Number
print(isinstance(n, int)) # True — Number унаследован от int
type() и isinstance() выходит за рамки лекции — это распространённая практика проверки типов в реальном коде. Сверьтесь с разделами isinstance() и type().
Что делать дальше
Посмотрите файлы репозитория — там те же идеи в исходном виде из лекции, затем переходите к заданиям. Если что-то не запустилось — загляните в типичные ошибки.