Основы языка
Что это такое
Основы Python — это части, из которых сделана любая программа: значения нескольких встроенных типов, имена, которые просто указывают на них, условия, циклы, функции, отступы, которые задают блоки, и аргументы со значениями по умолчанию. Типы здесь привязаны к значениям, а не к именам, и проверяются во время выполнения; этого достаточно, чтобы написать законченную программу, а всё дальнейшее строится на этом.
Почему это важно
Проектные решения языка проявляются именно здесь и определяют всё остальное: отступы — часть синтаксиса, поэтому форматирование не вопрос вкуса, а код читается одинаково везде. Типы привязаны к значениям, поэтому одно имя может хранить строку, а позже целое число; однако за гибкость приходится платить — ошибки типов всплывают во время выполнения, а не при сборке; имена же — не коробки, а ссылки, поэтому два имени могут указывать на один изменяемый объект, и отсюда берётся целое семейство ошибок, которые становятся очевидны, как только модель понята.
Ключевые идеи
Имена указывают на значения
Присваивание привязывает имя к объекту, а не копирует объект, поэтому два имени могут ссылаться на один список, и изменение через одно видно через другое. Типы принадлежат объектам, а не именам: одно имя можно переиспользовать для значений разных типов, и именно поэтому проверяющему типы нужны аннотации в помощь.
a = [1, 2]
b = a -> b — тот же список, что и a
b.append(3) -> теперь a равно [1, 2, 3]
Неизменяемые и изменяемые значения ведут себя по-разному
Числа, строки и кортежи после создания изменить нельзя, а списки, словари и множества можно. Одни значения поэтому безопасно делить между частями программы и брать в качестве ключей словаря, а другие опасно передавать в функции, которые могут изменить их на месте. Там, где данные меняться не должны, выбор неизменяемого значения убирает целый класс неожиданностей.
Отступы — это структура блоков
Фигурных скобок нет: блок задаёт согласованный отступ, а смешивать табуляции с пробелами интерпретатор не разрешает и проверяет это сам. Отсюда следствие, которое действительно помогает читать незнакомый код: любой файл на Python отформатирован похожим образом.
Функции — объекты, а у аргументов две конвенции
Функция — такое же значение, как любое другое, и её можно передавать: на этом держатся ключи сортировки, обратные вызовы и декораторы. Аргументы передают по позиции или по имени, и им можно задавать значения по умолчанию — с известной ловушкой: изменяемое значение по умолчанию создаётся один раз и делится между вызовами, поэтому накапливается.
Исключения — канал ошибок, и они должны быть конкретными
Пока исключение не поймают, оно распространяется вверх по стеку вызовов, и обработчику нужна прежде всего информация о его типе. Перехват всего подряд скрывает и ошибки программиста, и ожидаемые отказы, поэтому ловите самый узкий возможный тип — тогда неожиданные проблемы остаются видны.
Контекстный менеджер — стандартный шаблон работы с ресурсами
Файлы, блокировки и соединения поддерживают блок with, который гарантирует очистку даже при исключении. Закрывать ресурс вручную на каждом пути тогда не нужно, и потому это ожидаемая форма, а не украшение.
Практика
Покажите модель ссылок
Создайте список, присвойте его второму имени, измените через второе имя, а затем повторите опыт с кортежем.
Готово, когда: вы можете объяснить, почему список изменился, а кортеж вызвал ошибку.
Напишите функцию с безопасным значением по умолчанию
Напишите функцию с необязательным аргументом-списком, вызовите её дважды без аргумента и посмотрите на накопившийся результат; затем исправьте значение по умолчанию.
Готово, когда: два последовательных вызова без аргумента дают одинаковый результат.
Частые ошибки
- Изменяемое значение по умолчанию — значение разделяется между вызовами и накапливается; исправить: используйте по умолчанию
Noneи создавайте значение внутри. - Уверенность, что присваивание копирует — два имени делят один объект; исправить: копируйте намеренно, когда копия нужна.
- Перехват всех исключений — ошибки программиста скрываются вместе с ожидаемыми отказами; исправить: ловите самый узкий полезный тип.
- Открытие файла без контекстного менеджера — на пути ошибки закрытие пропускается; исправить: используйте
with. - Расчёт на то, что у переменной есть тип — ошибка появляется только при исполнении этой строки; исправить: аннотируйте типы и проверяйте их на границах.
Что читать дальше
- Программирование на Python (05-backend-data/03-python-programming) — язык, которому принадлежат эти основы, поэтому прочитайте сначала его.
- Данные и итерация (05-backend-data/03-python-programming/02-data-and-iteration) — коллекции и циклы, из которых состоит большая часть кода на Python.
- Конкурентность и асинхронное программирование (01-cs-fundamentals/05-concurrency-async-programming) — общая модель, на которой держатся асинхронные и потоковые возможности Python.