Примеры идут от простого к сложному: сначала переменные и правила имён, затем базовые типы и строки, затем типичные ловушки первых уроков, а в конце — обе практические задачи summary-сессии в развёрнутом виде. Весь вывод в комментариях получен реальным запуском кода (python file.py), а не написан по памяти.
Пример 1. Переменная — это имя, привязанное к значению
Присваивание не «превращает» переменную в определённый тип навсегда — оно просто связывает имя с объектом. Это база, на которой держится вся динамическая типизация Python.
# variables.py
coordinate1 = 42
user_name = "Alice"
_price = 10
print(coordinate1, user_name, _price)
print(type(coordinate1), type(user_name), type(_price))
coordinate1 = "now a string"
print(coordinate1, type(coordinate1))
# 42 Alice 10
# <class 'int'> <class 'str'> <class 'int'>
# now a string <class 'str'>
Что происходит: имя coordinate1 сначала указывает на число, затем — на строку. Ошибки нет: тип принадлежит объекту, на который ссылается имя, а не самому имени.
Пример 2. Правила имён переменных: допустимо / недопустимо
Имя может состоять из букв, цифр и _, но не должно начинаться с цифры, содержать дефис или совпадать с ключевым словом. Ниже — программная проверка вместо простого перечисления правил.
# naming_rules.py
import keyword
second_variable = "ok"
my_variable = "ok"
Var_1 = "ok"
print(second_variable, my_variable, Var_1)
print(keyword.iskeyword("if"), keyword.iskeyword("class"), keyword.iskeyword("total_value"))
bad_snippets = ["2nd_variable = 1", "my-variable = 1", "if = 1"]
for snippet in bad_snippets:
try:
compile(snippet, "<snippet>", "exec")
print(snippet, "-> compiled OK")
except SyntaxError as error:
print(snippet, "-> SyntaxError:", error)
# ok ok ok
# True True False
# 2nd_variable = 1 -> SyntaxError: invalid decimal literal (<snippet>, line 1)
# my-variable = 1 -> SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='? (<snippet>, line 1)
# if = 1 -> SyntaxError: invalid syntax (<snippet>, line 1)
Что происходит: Var_1 допустимо — регистр букв Python не ограничивает. compile() разбирает код без выполнения и бросает SyntaxError, если он нарушает грамматику языка — так же, как это делает интерпретатор при запуске файла.
keyword и приём с compile()/try except SyntaxError не упоминались в лекции — это дополнение курса, чтобы проверять правило именования кодом, а не только на глаз. См. keyword и compile().
Пример 3. print() и input(): первая интерактивная программа
input() всегда возвращает строку, даже если пользователь ввёл число — это самое частое недоразумение на старте курса.
# hello_input.py
name = input("Введите имя: ")
print("Привет, " + name + "!")
print(type(name))
# ввод: Alice
# Введите имя: Привет, Alice!
# <class 'str'>
Почему так: в примере выше подсказка "Введите имя: " печатается функцией input() без перевода строки, поэтому в захваченном выводе она прилипает к следующей строке. В обычном терминале между ними ещё будет виден ваш набранный текст — сама программа этого не печатает.
Пример 4. type() и базовые типы данных
type() — единственный надёжный способ узнать тип объекта в момент выполнения. Ниже все пять типов, изученных в первых двух уроках, — в одном списке.
# basic_types.py
values = [5, 5.0, "5", True, None]
for value in values:
print(repr(value), "->", type(value))
# 5 -> <class 'int'>
# 5.0 -> <class 'float'>
# '5' -> <class 'str'>
# True -> <class 'bool'>
# None -> <class 'NoneType'>
Что происходит: число 5 и строка "5" выглядят похоже, но это разные типы с разными допустимыми операциями — repr() в примере специально показывает кавычки, чтобы строку было видно.
Пример 5. Динамическая типизация: одно имя — разные типы
В Python переменную можно свободно переприсваивать значением другого типа. Это отличается от языков со статической типизацией, где тип переменной фиксируется один раз.
# dynamic_typing.py
value = 10
print(value, type(value))
value = "ten"
print(value, type(value))
value = 10.0
print(value, type(value))
# 10 <class 'int'>
# ten <class 'str'>
# 10.0 <class 'float'>
Почему так: каждое присваивание — это новая привязка имени к новому объекту. Старый объект просто перестаёт быть кому-либо доступен и удаляется сборщиком мусора.
Пример 6. Строки: конкатенация, повторение, кавычки, экранирование
Строки — самый частый тип на старте курса. Ниже собраны все операции и специальные символы, которые встречались в уроках 01–02.
# strings.py
print("Привет" + " " + "Python")
print("Hi! " * 3)
print("Строка1\nСтрока2")
print("Колонка1\tКолонка2")
print("Путь: C:\\Users")
print('Он сказал: "привет"')
text = """Первая строка
Вторая строка"""
print(text)
# Привет Python
# Hi! Hi! Hi!
# Строка1
# Строка2
# Колонка1 Колонка2
# Путь: C:\Users
# Он сказал: "привет"
# Первая строка
# Вторая строка
Что происходит: + склеивает строки без пробела, если не добавить его явно; * повторяет строку целиком; тройные кавычки позволяют записать перенос строки прямо в исходном коде, а одинарные и двойные кавычки можно вкладывать друг в друга, чтобы не экранировать кавычки внутри текста.
Пример 7. print(): управление выводом через sep и end
По умолчанию print() разделяет аргументы пробелом и завершает вывод переводом строки — оба параметра можно поменять.
# print_sep_end.py
print("Привет", "Python!")
print(1, 2, 3, 4, 5, sep="---")
print("Готово", end="!")
print()
print("a", "b", "c", sep="", end="\n\n")
# Привет Python!
# 1---2---3---4---5
# Готово!
# abc
# (и ещё одна пустая строка после abc)
Почему так: end="!" заменяет обычный перевод строки на "!", поэтому следующий вызов print() без аргументов сам добавляет перевод строки. sep="" убирает пробелы между аргументами полностью.
Пример 8. Ловушка: print() ничего не возвращает
print() — процедура: она выполняет действие (печать) и возвращает None. Сохранять её результат в переменную, чтобы использовать дальше, — частая ошибка новичков.
# print_returns_none.py
result = print("Hello")
print(result)
print(type(result))
# Hello
# None
# <class 'NoneType'>
Что происходит: первая строка печатает "Hello" на экран и одновременно присваивает result значение None — то, что вернула функция. Спутать это с самим выведенным текстом легко, если не проверить тип результата.
Пример 9. Комментарии и PEP 8: код работает одинаково, читается — по-разному
Комментарии и пробелы вокруг операторов не влияют на результат выполнения — но сильно влияют на то, насколько быстро код поймёт другой человек (и вы сами через неделю).
# style_pep8.py
# однострочный комментарий поясняет следующую строку
total_price=10*3+1 # так тоже работает, но трудно читать
total_price = 10 * 3 + 1 # так рекомендует PEP 8: пробелы вокруг операторов
print(total_price)
"""
Строка в тройных кавычках без присваивания — это просто выражение.
Интерпретатор его вычисляет и никуда не сохраняет, если она не первая
в теле функции или модуля (тогда она стала бы docstring).
"""
print("готово")
# 31
# готово
Почему так: обе записи total_price дают одно и то же число 31 — интерпретатору пробелы вокруг = и * безразличны. PEP 8 рекомендует писать со пробелами не ради интерпретатора, а ради читаемости.
Пример 10. Как устроено сообщение SyntaxError
Когда интерпретатор не может разобрать код, он не выполняет ни строчки и показывает, где именно разбор сломался. Это можно увидеть программно через compile(), не только по тексту ошибки в терминале.
# syntax_error_demo.py
broken_code = "if a == 5\n print('Hi')\n" # нет двоеточия после условия
try:
compile(broken_code, "<broken>", "exec")
except SyntaxError as error:
print("SyntaxError:", error)
print("lineno=%r, offset=%r, text=%r" % (error.lineno, error.offset, error.text))
# SyntaxError: expected ':' (<broken>, line 1)
# lineno=1, offset=10, text='if a == 5\n'
Что происходит: lineno и offset указывают точное место, где Python «споткнулся» — здесь не хватает двоеточия после условия if. Именно эти координаты вы видите подсвеченными, когда SyntaxError прерывает запуск обычного файла.
Пример 11. Практика: личное досье
Первая практическая задача summary-сессии: собрать три ответа пользователя в одну читаемую строку.
# personal_profile.py
name = input("Введите имя: ")
age = input("Введите возраст: ")
city = input("Введите город: ")
print(name + " " + age + " лет, проживает в городе " + city)
# ввод: Алиса / 25 / Париж
# Алиса 25 лет, проживает в городе Париж
Что происходит: все три значения — строки (input() не возвращает ничего другого), поэтому их можно склеивать оператором + напрямую, без преобразования типов.
Пример 12. Практика: повторитель текста — два способа
Вторая задача: вывести введённый текст трижды. Прямолинейный способ из лекции — три вызова print(); более компактный — цикл или повторение строки.
# text_repeater.py
text = input("Введите текст: ")
print(text)
print(text)
print(text)
# ввод: Python is fun
# Python is fun
# Python is fun
# Python is fun
# text_repeater_compact.py
text = input("Введите текст: ")
print((text + "\n") * 3, end="")
# ввод: Python is fun
# Python is fun
# Python is fun
# Python is fun
Почему так: оба варианта дают одинаковый вывод. Три отдельных print(text) нагляднее для самого первого занятия; (text + "\n") * 3 — тот же результат за счёт повторения строки, но требует понимать, что print() сам добавляет перевод строки, поэтому здесь его гасят через end="".
Что дальше
Если что-то из примеров не запустилось — загляните в типичные ошибки. Тема продолжается в уроке 04 — арифметические операторы и выражения, а сравнения (==, >, <) и ветвление разбираются в уроке 06 и уроке 08.