Обучение языку Python

Курс познакомит с основами Python и поможет уверенно писать программы: от синтаксиса и типов данных до функций, модулей и ООП. Вы научитесь работать с файлами, обрабатывать ошибки и применять популярные библиотеки для практических задач.

1. Введение в Python и настройка среды разработки

Введение в Python и настройка среды разработки

Что такое Python и почему его выбирают

Python — это язык программирования, на котором можно писать как небольшие скрипты для автоматизации, так и крупные приложения. Его часто выбирают из-за:

  • Простого и читаемого синтаксиса
  • Большого количества готовых библиотек
  • Кроссплатформенности (Windows, macOS, Linux)
  • Широкого применения: анализ данных, веб-разработка, тестирование, автоматизация, обучение
  • В этом курсе мы будем последовательно учиться:

  • Запускать Python-код
  • Писать программы в файлах
  • Устанавливать сторонние пакеты
  • Организовывать проекты так, как это делают разработчики
  • Как устроена работа с Python на практике

    Обычно процесс выглядит так:

  • Вы создаёте папку проекта
  • Настраиваете изолированную среду (виртуальное окружение)
  • Пишете код в файлах .py
  • Запускаете код и проверяете результат
  • При необходимости устанавливаете дополнительные пакеты через pip
  • !Схема типичного цикла работы: проект → venv → файл с кодом → запуск → результат

    Установка Python

    Проверка: возможно, Python уже установлен

    Откройте терминал:

  • Windows: PowerShell или Командная строка
  • macOS: Terminal
  • Linux: терминал вашей системы
  • Введите команду:

    Если система не находит python, попробуйте:

    Установка с официального сайта

    Скачивайте Python с официальной страницы загрузок:

  • Python Downloads
  • Рекомендации:

  • Устанавливайте актуальную стабильную версию Python 3
  • На Windows во время установки включите опцию Add Python to PATH (это позволит запускать python из терминала)
  • После установки снова проверьте версию командой python --version (или python3 --version).

    Терминал и первый запуск Python

    Python можно использовать двумя основными способами:

  • Интерактивно (REPL) — вводите команды по одной строке и сразу видите результат
  • Через файл — пишете программу в .py и запускаете её
  • Интерактивный режим (REPL)

    Запустите:

    Вы окажетесь внутри Python. Попробуйте:

    Чтобы выйти:

  • Windows: Ctrl+Z, затем Enter
  • macOS/Linux: Ctrl+D
  • Запуск программы из файла

  • Создайте папку проекта, например python-course.
  • Внутри создайте файл main.py со следующим содержимым:
  • Запустите из терминала, находясь в папке проекта:
  • Если python не распознаётся, используйте python3 main.py.

    Менеджер пакетов pip

    pip — это инструмент для установки сторонних библиотек (пакетов). Например, если вам понадобится библиотека, которой нет в стандартной поставке Python, вы установите её через pip.

    Проверка версии pip:

    Если не работает, часто помогает вариант:

    Полезная справка:

  • pip documentation
  • Важно: пакеты лучше ставить не “в систему”, а в виртуальное окружение проекта (об этом далее).

    Виртуальные окружения (venv)

    Виртуальное окружение — это отдельная папка со своей копией интерпретатора и установленными пакетами. Оно нужно, чтобы:

  • Разные проекты не конфликтовали по версиям библиотек
  • Было проще воспроизводить окружение на другом компьютере
  • “Не засорять” глобальную установку Python
  • Создание виртуального окружения

    Находясь в папке проекта:

    Это создаст папку .venv с окружением.

    Официальная документация:

  • venv — Creation of virtual environments
  • Активация виртуального окружения

    Windows (PowerShell):

    Windows (cmd):

    macOS/Linux:

    После активации в терминале обычно появляется префикс с именем окружения (например, (.venv)), и все установки через pip будут идти именно в это окружение.

    Установка пакета в окружение

    Пример установки пакета:

    Проверка, что пакет установлен:

    Отключение окружения:

    Редактор кода: что выбрать

    Вам нужен редактор/IDE, который умеет:

  • Подсветку синтаксиса
  • Автодополнение
  • Запуск программ
  • Работу с виртуальными окружениями
  • Visual Studio Code

    Популярный бесплатный редактор, который хорошо подходит для Python.

  • Visual Studio Code
  • Рекомендуемое расширение:

  • Python extension for Visual Studio Code
  • Что важно настроить в VS Code:

  • Выбрать интерпретатор из вашего окружения .venv
  • Запускать скрипты из терминала, где активировано окружение
  • PyCharm

    IDE для Python с мощными инструментами.

  • PyCharm
  • При создании проекта укажите использование виртуального окружения .venv (или создайте новое через интерфейс PyCharm).

    Типичные проблемы и быстрые решения

  • Команда python не находится
  • - На Windows переустановите Python с включённой опцией Add Python to PATH - Попробуйте python3 вместо python

  • pip не работает
  • - Используйте python -m pip ... вместо pip ...

  • Пакеты “как будто не установились”
  • - Проверьте, что виртуальное окружение активировано - Проверьте, какой интерпретатор используется в IDE

    Итоги

    Теперь у вас должно быть:

  • Установлен Python 3
  • Понимание разницы между REPL и запуском .py файлов
  • Настроен терминал для запуска команд python и pip
  • Создано и активируется виртуальное окружение .venv
  • Выбран редактор (VS Code или PyCharm) и понятен принцип выбора интерпретатора проекта
  • В следующей статье мы начнём писать первые программы и разберём базовые элементы языка: переменные, типы данных и простые операции.

    2. Синтаксис, переменные и базовые типы данных

    Синтаксис, переменные и базовые типы данных

    Как связана эта тема с предыдущей статьёй

    В прошлой статье вы установили Python, научились запускать код в REPL и из файла .py, а также настроили виртуальное окружение. Теперь мы разберём как писать корректный Python-код: его синтаксис, правила именования, переменные и основные типы данных. Все примеры можно запускать в main.py вашего проекта или в REPL.

    Синтаксис Python: что важно с самого начала

    Блоки кода и отступы

    В Python блоки кода задаются отступами, а не фигурными скобками.

    Пример с условием:

    Правила:

  • После строк, которые открывают блок (if, for, while, def, class, try), ставится двоеточие :
  • Внутри блока одинаковый отступ на каждой строке
  • На практике почти всегда используют 4 пробела на уровень отступа
  • > Если вы случайно смешаете табы и пробелы или нарушите отступы, Python выдаст ошибку IndentationError.

    Инструкции и выражения

    Полезно различать два понятия:

  • Выражение — то, что вычисляется в значение (например, 2 + 2, name.upper(), len(text))
  • Инструкция — действие (например, присваивание x = 10, импорт import math, условие if ...:)
  • На практике это различие помогает понимать сообщения об ошибках и то, что можно написать в конкретном месте программы.

    Комментарии

    Комментарии нужны, чтобы пояснять почему сделано так, а не что делает очевидный код.

    Рекомендации по стилю

    Самые базовые и общепринятые правила описаны в PEP 8:

  • PEP 8 — Style Guide for Python Code
  • Для старта достаточно запомнить:

  • Имена переменных обычно пишут в стиле snake_case
  • Отступы — 4 пробела
  • Вокруг операторов обычно ставят пробелы: a + b, x = 10
  • Переменные: присваивание и имена

    Что такое переменная в Python

    Переменная — это имя, которое ссылается на значение.

    Важно:

  • В Python тип принадлежит значению, а не имени переменной
  • Одна и та же переменная может начать ссылаться на значение другого типа
  • !Схема показывает, что переменная — это имя, которое ссылается на значение, и что ссылку можно поменять

    Правила именования

    Разрешено:

  • Буквы, цифры и символ _
  • Имя не может начинаться с цифры
  • Регистр важен: age и Age — разные имена
  • Нельзя:

  • Использовать ключевые слова Python (например, if, for, class)
  • Проверить список ключевых слов можно так:

    Частые ошибки новичков

  • Путаница = и ==
  • Попытка прочитать переменную до присваивания (ошибка NameError)
  • Базовые типы данных

    Числа: int и float

  • int — целые числа: -5, 0, 42
  • float — числа с точкой: 3.14, 0.5
  • Замечание про float:

  • float хранится приближённо, поэтому иногда видны «хвосты»
  • Строки: str

    Строка — это последовательность символов.

    Частые операции:

    Полезно помнить:

  • Индексация начинается с 0
  • Строки в Python неизменяемые (нельзя поменять символ по индексу)
  • Логический тип: bool

    bool имеет два значения: True и False.

    Часто используется в условиях:

    Логические операторы:

    Специальное значение: None

    None означает «нет значения» или «значение неизвестно».

    Обычно None используют, когда:

  • Значение появится позже
  • Функция ничего осмысленного не возвращает
  • Нужно явно обозначить отсутствие данных
  • Проверять лучше так:

    Преобразования типов

    Иногда данные приходят в виде строки (например, из input()), а вам нужно число.

    Частые преобразования:

    Важно:

  • int("3.5") вызовет ошибку, потому что это не целое число
  • bool("") даст False, а bool("0") даст True, потому что непустая строка считается истинной
  • Как узнать тип значения и что это вам даёт

    Для проверки типа используют type():

    Практическое применение:

  • Понимать, почему операция не работает (например, нельзя сложить строку и число)
  • Проверять данные, которые вы получили извне (ввод пользователя, файл, сеть)
  • Мини-словарь операторов и функций, которые вы уже должны узнавать

    | Элемент | Пример | Что делает | |---|---|---| | Присваивание | x = 5 | Связывает имя x со значением 5 | | Равенство | x == 5 | Сравнивает значения, результат True или False | | Сложение | a + b | Складывает числа или соединяет строки | | Длина | len("abc") | Возвращает количество элементов | | Печать | print(x) | Выводит значение в консоль | | Тип | type(x) | Показывает тип значения |

    Итоги

    В этой статье вы научились:

  • Понимать роль отступов и блоков кода в Python
  • Использовать комментарии и базовые правила оформления
  • Создавать переменные, выбирать корректные имена и избегать частых ошибок
  • Работать с базовыми типами: int, float, str, bool, None
  • Делать преобразования типов и проверять тип через type()
  • Дальше логичный шаг — научиться писать небольшие программы с ветвлениями и циклами, где эти типы и переменные начинают работать вместе.

    3. Условия, циклы и базовые структуры данных

    Условия, циклы и базовые структуры данных

    Связь с предыдущими темами

    Ранее вы настроили среду разработки, научились запускать .py-файлы и разобрали переменные и базовые типы (int, float, str, bool, None). Теперь мы соберём эти элементы в управляемые программы: добавим ветвления, повторения (циклы) и структуры данных, которые позволяют хранить несколько значений.

    Полезные разделы документации Python:

  • The Python Tutorial — More Control Flow Tools
  • The Python Tutorial — Data Structures
  • Built-in Types
  • Условия

    Условие позволяет выполнить разные действия в зависимости от данных.

    Конструкция if / elif / else

    Правила:

  • После if, elif, else ставится :
  • Внутри блока используются отступы (обычно 4 пробела)
  • elif можно использовать много раз, else необязателен
  • !Как работает ветвление if/elif/else

    Сравнения и логические операторы

    Чаще всего в условиях используются операторы сравнения:

  • == равно
  • != не равно
  • > больше
  • < меньше
  • >= больше или равно
  • <= меньше или равно
  • Логические операторы:

  • and — истинно, если истинны оба условия
  • or — истинно, если истинно хотя бы одно условие
  • not — инвертирует значение
  • Истинность значений (truthiness)

    В if можно писать не только True/False, но и другие значения. Python интерпретирует некоторые значения как ложные:

  • False
  • None
  • 0 и 0.0
  • пустая строка ""
  • пустые структуры данных: [], {}, set(), ()
  • Пример:

    Частая ошибка: = вместо ==

    = — присваивание, == — сравнение.

    Циклы

    Циклы нужны, чтобы повторять действия.

    Цикл for: перебор последовательностей

    for обычно используют, когда нужно пройти по набору значений.

    Часто вместе с for используют range() для последовательности чисел:

    Если нужно начать не с нуля или задать шаг:

    Цикл while: повторение, пока условие истинно

    while используют, когда заранее неизвестно, сколько будет повторений.

    Важно:

  • Следите, чтобы условие когда-нибудь стало ложным
  • Иначе получится бесконечный цикл
  • break и continue

  • break полностью прекращает цикл
  • continue пропускает текущую итерацию и переходит к следующей
  • enumerate: индекс и значение

    Если нужен и индекс, и элемент, удобно использовать enumerate():

    Базовые структуры данных

    Структуры данных позволяют хранить несколько значений и работать с ними как с единым объектом.

    !Сравнение list, tuple, dict и set

    Списки (list)

    Список — упорядоченная изменяемая коллекция.

    Создание и доступ по индексу:

    Изменение:

    Частые операции:

  • append(x) — добавить в конец
  • pop() — удалить и вернуть последний элемент
  • len(nums) — длина
  • x in nums — проверка наличия
  • Перебор списка:

    Кортежи (tuple)

    Кортеж — упорядоченная неизменяемая коллекция.

    Если попытаться изменить кортеж, будет ошибка:

    Зачем нужны кортежи:

  • Зафиксировать набор значений, который не должен меняться
  • Удобно возвращать несколько значений из функции (позже в курсе)
  • Словари (dict)

    Словарь хранит пары ключ → значение. Ключ обычно делают строкой или числом.

    Добавление и изменение:

    Безопасное получение через get():

    Перебор словаря:

    Множества (set)

    Множество — коллекция уникальных элементов, без индексации.

    Полезные операции:

    Проверка уникальности через множество:

    Как всё соединяется в небольшой программе

    Пример: посчитать, сколько раз встречается каждое слово.

    Здесь вместе работают:

  • for для перебора списка
  • if для проверки, видели ли мы слово раньше
  • dict для хранения результата
  • Итоги

    Теперь вы умеете:

  • Писать ветвления через if / elif / else
  • Использовать сравнения и логические операторы and, or, not
  • Понимать, какие значения считаются истинными и ложными в условиях
  • Работать с циклами for и while, применять break и continue
  • Использовать базовые структуры данных: list, tuple, dict, set
  • Дальше по курсу обычно переходят к функциям: как упаковывать логику в переиспользуемые блоки и аккуратно передавать данные между частями программы.

    4. Функции, области видимости и работа с модулями

    Функции, области видимости и работа с модулями

    Как эта тема продолжает курс

    В прошлой статье вы научились управлять выполнением программы с помощью if, for, while, а также хранить данные в list, dict, set, tuple. Следующий шаг — научиться упаковывать повторяющуюся логику в функции и организовывать код по файлам (модулям), чтобы проекты оставались понятными и расширяемыми.

    Официальная документация Python по теме:

  • Defining Functions
  • More on Defining Functions
  • Scopes and Namespaces Example
  • Modules
  • Функции

    Зачем нужны функции

    Функция — это именованный блок кода, который можно вызывать много раз.

    Функции помогают:

  • Убирать дублирование кода
  • Делать программу читаемой (давать понятные имена действиям)
  • Проще тестировать части программы
  • Разделять ответственность: ввод данных, обработка, вывод результата
  • Объявление функции: def

    Минимальный пример:

    Что важно:

  • def создаёт функцию
  • После имени функции пишутся скобки ()
  • Тело функции — это блок с отступами
  • Параметры (входные данные)

    Чтобы функция работала с разными значениями, ей передают параметры.

    Здесь name — параметр, а строка при вызове ("Маша") — аргумент.

    return: возвращаем результат

    print() показывает значение на экране, но не возвращает его.

    Функция с return отдаёт результат вызывающему коду:

    Правила:

  • return сразу завершает выполнение функции
  • Если return не написан, функция возвращает None
  • Пример:

    Несколько return и ранний выход

    Это часто используют вместе с условиями для валидации данных.

    Значения по умолчанию

    Можно задавать значения параметров по умолчанию.

    Важно: аргументы по умолчанию вычисляются при создании функции. Поэтому не используйте изменяемые значения (например, [], {}) как значение по умолчанию.

    Плохой пример:

    Правильный подход:

    Именованные аргументы

    Аргументы можно передавать по имени — это повышает читаемость.

    Докстроки: краткая документация к функции

    Докстрока — это строка в начале тела функции. Её используют IDE, справка help() и инструменты документации.

    Области видимости: где живут имена

    Когда вы пишете x = 10, вы создаёте имя x, которое указывает на значение. Область видимости отвечает на вопрос: в какой части программы это имя доступно.

    !Схема поиска имени по областям видимости (local → enclosing → global → builtins)

    Локальная область (внутри функции)

    Имена, созданные внутри функции, обычно видны только внутри неё.

    Это защищает код от случайных конфликтов имён.

    Глобальная область (уровень модуля)

    Если имя объявлено в файле вне функций, оно глобальное для этого модуля.

    Важно различать чтение и изменение.

    Частая ошибка: попытка изменить глобальную переменную внутри функции

    Почему так происходит:

  • Python видит присваивание count = ... и решает, что count — локальная
  • Но локальная count ещё не создана, когда справа выполняется count + 1
  • Решения:

  • Лучше всего: возвращайте новое значение и присваивайте снаружи
  • Если очень нужно изменить глобальную переменную, используйте global (редко полезно в учебных и небольших скриптах, но важно знать)
  • nonlocal: изменение переменной во внешней функции

    nonlocal нужен, когда есть вложенные функции.

    Если не использовать nonlocal, будет та же проблема, что и с глобальной переменной: Python решит, что count локальная для inc().

    Практическое правило

    Чтобы избежать ошибок с областями видимости:

  • Храните данные в переменных и структурах данных снаружи, а функции делайте чистыми: принимают входные данные и возвращают результат
  • Используйте global и nonlocal только когда понимаете, зачем это нужно
  • Модули: организация кода по файлам

    Что такое модуль

    Модуль — это файл .py, который можно импортировать.

    Например, если у вас есть файл utils.py, то это модуль utils.

    Python поставляется со стандартной библиотекой модулей (например, math, random, json). Также можно ставить сторонние пакеты через pip в ваше виртуальное окружение .venv, которое вы настроили в первой статье.

    Импорт модулей: import и from ... import ...

    Импорт конкретного имени:

    Импорт с псевдонимом:

    Рекомендации:

  • import module обычно читается лучше и снижает риск конфликтов имён
  • from module import name удобно, когда имя используется очень часто
  • Как Python находит модули

    Упрощённо, Python ищет модуль:

  • В текущей папке проекта
  • В папках стандартной библиотеки
  • В установленных пакетах текущего окружения (поэтому важно активировать .venv)
  • Посмотреть, где Python ищет модули, можно так:

    Пример: разделяем проект на файлы

    Структура проекта:

  • main.py
  • utils.py
  • utils.py:

    main.py:

    if __name__ == "__main__": запуск как скрипт

    Один и тот же файл может быть:

  • скриптом, который запускают напрямую
  • модулем, который импортируют
  • Для этого используют проверку __name__.

    utils.py:

    Поведение:

  • Если выполнить python utils.py, запустится _demo()
  • Если сделать import utils, _demo() не выполнится, и модуль будет безопасно импортироваться
  • Чуть аккуратнее про имя модуля

    При импорте import utils вы обращаетесь к функциям так:

    Это часто удобнее, чем импортировать много функций напрямую, потому что видно, откуда пришло имя.

    Итоги

    Теперь вы умеете:

  • Создавать функции через def, передавать параметры и возвращать значения через return
  • Использовать значения по умолчанию и именованные аргументы
  • Понимать разницу между print() и return
  • Разбираться с областями видимости: локальной и глобальной, а также знать, зачем нужны global и nonlocal
  • Разносить код по модулям и импортировать его через import и from ... import ...
  • Защищать запускаемый код модуля конструкцией if __name__ == "__main__"
  • 5. Файлы, исключения и основы тестирования

    Файлы, исключения и основы тестирования

    Как эта тема продолжает курс

    Раньше вы научились писать программы с условиями и циклами, хранить данные в структурах (list, dict, set) и выносить логику в функции и модули. Теперь добавим три практических навыка, без которых сложно писать надёжные программы:

  • чтение и запись файлов
  • обработка ошибок через исключения
  • базовое тестирование функций
  • Полезные разделы документаации:

  • Built-in Exceptions
  • Errors and Exceptions
  • Reading and Writing Files
  • unittest — Unit testing framework
  • Файлы

    Файл — это данные, которые лежат на диске. В Python обычно работают с файлами так:

  • Открывают файл
  • Читают или пишут
  • Закрывают файл
  • Самое важное правило: файл должен быть закрыт даже при ошибках. Для этого используется контекстный менеджер with.

    !Автоматическое закрытие файла при использовании with

    Открытие файла и режимы

    Файл открывают встроенной функцией open().

    Так делать можно, но лучше использовать with.

    Основные режимы (второй аргумент open):

  • "r" — чтение (файл должен существовать)
  • "w" — запись (файл перезапишется, если существовал)
  • "a" — дозапись в конец
  • "x" — создать новый файл (если уже есть, будет ошибка)
  • Часто также встречается бинарный режим (например, для картинок):

  • "rb" — чтение байтов
  • "wb" — запись байтов
  • Контекстный менеджер with

    with гарантирует закрытие файла.

    Чтение файла

    Самые частые варианты:

  • read() читает всё содержимое целиком
  • readline() читает одну строку
  • итерация по файлу читает построчно (обычно самый удобный и экономный по памяти способ)
  • Пример построчного чтения:

    Запись в файл

    Запись строкой:

    Запись списка строк:

    Важно:

  • write() и writelines() не добавляют перевод строки автоматически
  • режим "w" перезаписывает файл целиком
  • Пути к файлам и pathlib

    Если вы пишете проекты, удобнее работать с путями через pathlib.

    Плюсы pathlib:

  • удобно склеивать пути через /
  • меньше ручной работы со строками путей
  • Типичные проблемы с файлами

  • Файл не найден
  • В этом случае будет исключение FileNotFoundError.

  • Ошибка кодировки
  • Если файл содержит не UTF-8, чтение с encoding="utf-8" может вызвать UnicodeDecodeError. В реальных проектах кодировку нужно уточнять, а в учебных примерах мы будем придерживаться UTF-8.

    Исключения

    Исключение — это сигнал об ошибке во время выполнения программы. Например:

  • деление на ноль: ZeroDivisionError
  • неправильное преобразование типа: ValueError
  • файл не найден: FileNotFoundError
  • Если исключение не обработано, программа обычно завершается и печатает traceback (стек вызовов), который помогает понять, где произошла ошибка.

    Обработка исключений: try / except

    Что здесь важно:

  • в try помещают код, который может упасть
  • в except обрабатывают конкретные исключения
  • Получение объекта исключения

    Иногда нужно вывести деталь ошибки.

    else и finally

  • else выполняется, если ошибок не было
  • finally выполняется всегда (и при успехе, и при ошибке)
  • !Поток выполнения try/except/else/finally

    Когда стоит ловить исключения

    Практическое правило:

  • ловите исключения там, где вы можете с ними что-то разумное сделать
  • не пишите except Exception: без необходимости, иначе можно скрыть реальные баги
  • Создание собственных ошибок: raise

    Иногда лучше не пытаться «починить» всё внутри функции, а честно сообщить вызывающему коду, что данные неправильные.

    Такую функцию проще тестировать и переиспользовать: она либо возвращает корректный результат, либо явно падает.

    Основы тестирования

    Тесты нужны, чтобы автоматически проверять, что функции работают правильно. Это особенно полезно, когда вы:

  • рефакторите код (переписываете его, не меняя поведение)
  • добавляете новые случаи и не хотите сломать старые
  • делите код на модули и хотите быстро проверять логику
  • Что обычно тестируют

    Чаще всего тестируют функции, которые:

  • принимают входные данные
  • возвращают результат
  • не зависят от input() и print()
  • Это продолжает идею из прошлой статьи: полезно писать функции, которые возвращают значения через return, а не только печатают.

    Тестирование через unittest

    unittest — модуль стандартной библиотеки, его не нужно устанавливать.

    Пример структуры проекта:

  • utils.py
  • test_utils.py
  • utils.py:

    test_utils.py:

    Запуск:

    Что здесь происходит:

  • класс наследуется от unittest.TestCase
  • тестовые методы начинаются с test_
  • assertEqual сравнивает ожидаемое и фактическое значение
  • assertRaises проверяет, что код внутри действительно выбрасывает исключение
  • Коротко про pytest (по желанию)

    Многие проекты используют pytest, потому что он позволяет писать тесты короче. Это сторонний пакет.

    Документация:

  • pytest documentation
  • Установка в виртуальное окружение:

    Минимальный пример (файл test_utils_pytest.py):

    Запуск:

    Пример: чтение файла и безопасная обработка ошибок

    Допустим, у вас файл numbers.txt, в котором по одному числу на строку. Нужно прочитать файл и посчитать сумму, пропуская пустые строки.

    Здесь собраны сразу несколько идей курса:

  • логика вынесена в функцию
  • чтение файла сделано через with
  • ошибки не скрываются: при некорректной строке мы явно сообщаем, где проблема
  • Итоги

    Теперь вы умеете:

  • читать и писать файлы, использовать режимы r, w, a
  • безопасно работать с файлами через with open(...) as f:
  • понимать, что такое исключения, и обрабатывать их через try / except / else / finally
  • выбрасывать ошибки через raise, когда входные данные некорректны
  • писать простые автотесты для функций с помощью unittest и проверять исключения
  • 6. ООП в Python: классы, наследование, магические методы

    ООП в Python: классы, наследование, магические методы

    Как эта тема продолжает курс

    Ранее вы научились писать функции, разбивать код на модули, работать с файлами и исключениями, а также писать простые тесты. Объектно-ориентированное программирование (ООП) добавляет ещё один способ организовывать код: объединять данные и поведение в одну сущность.

    Это особенно полезно, когда:

  • в программе есть несколько связанных сущностей (пользователь, заказ, товар)
  • важно хранить состояние (например, баланс счёта)
  • нужно расширять поведение без переписывания старого кода
  • Полезные источники:

  • Python Tutorial: Classes
  • Python Data Model (магические методы)
  • Базовые понятия ООП

    Класс — это шаблон (описание) того, какие данные и действия есть у сущности.

    Объект (или экземпляр класса) — конкретная созданная сущность по этому шаблону.

    Пример из жизни:

  • класс: User (описание пользователя)
  • объект: пользователь Маша, созданный по классу User
  • !Диаграмма "класс → объекты" показывает, что класс является шаблоном, а объекты — конкретными экземплярами

    Создание классов и объектов

    Минимальный класс

    User() создаёт новый объект класса User.

    Атрибуты объекта

    Атрибуты можно создавать динамически, но так обычно делать не стоит для реальных проектов: легко ошибиться в имени.

    Правильнее задавать атрибуты в конструкторе.

    Конструктор __init__

    __init__ — специальный метод, который вызывается при создании объекта.

    Что здесь важно:

  • self — ссылка на текущий объект
  • self.name и self.age — атрибуты, которые сохраняются внутри объекта
  • Методы (поведение объекта)

    Метод — это функция, объявленная внутри класса.

    Практическое правило: метод должен либо:

  • возвращать результат через return (удобно для тестов)
  • либо выполнять эффект (например, писать в файл), но тогда сложнее тестировать
  • Атрибуты класса и атрибуты объекта

    В Python атрибут может принадлежать:

  • объекту (у каждого объекта своё значение)
  • классу (общее значение для всех объектов)
  • Если изменить атрибут класса через имя класса, его увидят все объекты:

    Если же присвоить u1.species = ..., то вы создадите атрибут объекта, который перекроет значение класса только для этого объекта.

    Инкапсуляция по-питоновски: соглашения об именах

    В Python нет жёсткого запрета на доступ к полям, как в некоторых языках. Вместо этого используются соглашения:

  • name — публичный атрибут
  • _nameвнутренний атрибут, который не предполагается использовать снаружи
  • __name — имя будет изменено механизмом name mangling (защита от случайного конфликта имён в наследниках)
  • Пример с _balance:

    Здесь исключение ValueError продолжает идею из прошлой статьи: лучше явно сообщить об ошибке, чем молча принять некорректные данные.

    Свойства property: контроль доступа к данным

    Если вы хотите оставить доступ как к атрибуту, но добавить проверки, используйте property.

    Плюс такого подхода: внешний код работает с t.celsius как с обычным атрибутом, а класс сохраняет контроль над корректностью.

    Наследование: расширяем и переиспользуем поведение

    Наследование позволяет создать новый класс на основе существующего.

  • базовый класс (родитель): содержит общую логику
  • дочерний класс (наследник): расширяет или переопределяет поведение
  • !Схема показывает, что наследники берут основу из базового класса и могут переопределять методы

    Пример: базовый класс и переопределение метода

    Это пример полиморфизма: разные объекты отвечают на один и тот же вызов speak() по-разному.

    super(): вызов логики родителя

    Если вы переопределяете __init__, часто нужно вызвать __init__ родителя.

    Практическое правило:

  • используйте super() вместо прямого вызова User.__init__(...), это лучше работает в сложных цепочках наследования
  • Композиция вместо наследования (когда это проще)

    Наследование удобно, когда действительно есть отношение является.

  • Admin является User
  • Композиция удобна, когда отношение имеет.

  • Order имеет items
  • Report имеет writer (объект, который умеет писать файл)
  • Пример композиции:

    Такое решение легко тестировать: в тестах можно передать другой логгер (например, который пишет в список).

    Магические методы (dunder methods)

    Магические методы — это методы со специальными именами вида __name__. Python вызывает их автоматически в ответ на привычные операции.

    Документация: Python Data Model (Special method names)

    __str__ и __repr__: как объект выглядит в тексте

  • __str__ — “красивый” вывод для пользователя
  • __repr__ — более техническое представление (полезно для отладки)
  • __len__: поддержка len(obj)

    Сравнение объектов: __eq__

    По умолчанию a == b для объектов без __eq__ часто означает сравнение по идентичности (по сути, “это один и тот же объект или нет”). Если нужно сравнивать по данным, определите __eq__.

    Здесь NotImplemented означает: “я не знаю, как сравнивать с этим типом, пусть Python попробует другой вариант”.

    Арифметика: __add__

    Контекстный менеджер: __enter__ и __exit__

    Конструкция with из прошлой статьи работает благодаря магическим методам.

    Упрощённо:

  • with obj as x: вызывает obj.__enter__()
  • при выходе из блока вызывается obj.__exit__(...) даже если внутри была ошибка
  • Именно поэтому файлы закрываются автоматически.

    Как это связывается с тестированием

    ООП-код хорошо тестируется, если вы придерживаетесь идеи из предыдущих тем:

  • методы возвращают значения, а не только печатают
  • операции с внешним миром (файлы, сеть) спрятаны за небольшими классами, которые можно заменить в тестах
  • при ошибках выбрасываются понятные исключения (ValueError, FileNotFoundError), а не возвращаются “магические” значения
  • Итоги

    Теперь вы знаете основы ООП в Python:

  • как создавать классы и объекты
  • как работать с атрибутами и методами, зачем нужен self
  • чем отличаются атрибуты класса и объекта
  • как применять наследование, переопределение методов и super()
  • что такое магические методы и как они подключают объект к операциям Python (print, len, ==, +, with)
  • Дальше можно углубляться в более прикладные темы: проектирование классов, протоколы коллекций (__iter__), датаклассы, а также более серьёзное тестирование кода, построенного на объектах.

    7. Практика: работа с библиотеками и мини-проект

    Практика: работа с библиотеками и мини-проект

    Зачем нужна практика с библиотеками

    На предыдущих этапах курса вы научились писать функции, делить код на модули, работать с файлами и исключениями, а также познакомились с ООП. В реальной разработке следующий шаг почти всегда один: подключить библиотеки и собрать небольшое приложение, которое решает задачу целиком.

    Библиотеки в Python бывают двух типов:

  • Стандартная библиотека идёт вместе с Python (например, json, argparse, pathlib, datetime, logging, unittest).
  • Сторонние пакеты устанавливаются через pip в виртуальное окружение (например, requests).
  • Цель этой статьи: собрать мини-проект консольный погодный клиент, который ходит в публичное API, обрабатывает JSON, кэширует результат в файл, аккуратно обрабатывает ошибки и покрывает часть логики тестами.

    Минимальный набор навыков работы с библиотекой

    Когда вы берёте новую библиотеку, полезно действовать по одному и тому же алгоритму:

  • Найти официальную документацию.
  • Найти минимальный пример использования.
  • Понять типы входных данных и формат результата.
  • Выписать возможные ошибки и способы обработки.
  • Изолировать внешние эффекты (сеть, файлы) от “чистой” логики, чтобы было проще тестировать.
  • Для мини-проекта нам пригодятся:

  • requests для HTTP-запросов: Requests: HTTP for Humans
  • argparse для аргументов командной строки: argparse — Parser for command-line options
  • json для работы с JSON: json — JSON encoder and decoder
  • pathlib для путей и файлов: pathlib — Object-oriented filesystem paths
  • logging для логов: logging — Logging facility for Python
  • unittest для тестов: unittest — Unit testing framework
  • Мини-проект: консольный погодный клиент

    Что будет делать программа

    Программа будет:

  • принимать широту и долготу через аргументы командной строки
  • обращаться к публичному API и получать погоду в формате JSON
  • выводить температуру и скорость ветра
  • кэшировать ответ в файл и использовать кэш, если он ещё “свежий”
  • Мы будем использовать API Open-Meteo, оно не требует ключа: Open-Meteo API Documentation

    Как выглядит общий поток выполнения

    !Схема: аргументы → запрос → JSON → парсинг → кэш → вывод

    Подготовка проекта и установка пакетов

    Структура проекта

    Создайте папку проекта, например weather-cli, и сделайте структуру:

  • src/
  • src/weather/
  • src/weather/__init__.py
  • src/weather/api.py
  • src/weather/cache.py
  • src/weather/cli.py
  • tests/
  • tests/test_parsing.py
  • Виртуальное окружение и установка requests

    В папке проекта:

    Активируйте окружение и установите пакет:

    Чтобы зафиксировать зависимости, часто создают файл requirements.txt:

    Важно: файл requirements.txt помогает воспроизвести окружение на другом компьютере.

    Реализация: работа с API и JSON

    Немного терминов без усложнений

  • HTTP-запрос это обращение программы к серверу по адресу (URL).
  • API это “контракт” того, какие запросы можно делать и какие данные придут в ответ.
  • JSON это текстовый формат, похожий на словари и списки Python.
  • Модуль api.py: запрос и минимальная валидация ответа

    src/weather/api.py:

    Что здесь важно:

  • requests.get(...) делает HTTP GET-запрос.
  • timeout нужен, чтобы программа не зависала бесконечно при проблемах сети.
  • raise_for_status() превращает коды 4xx/5xx в исключение.
  • parse_weather отделён от сетевого кода, чтобы его было легко тестировать.
  • > Обратите внимание: мы выбрасываем понятные исключения (ValueError и RuntimeError), а не возвращаем “магические” значения. Это продолжает подход из темы про исключения.

    Реализация: кэширование ответа в файл

    Кэширование полезно, когда вы не хотите постоянно ходить в сеть, а данные меняются не каждую секунду.

    Сделаем кэш “свежим”, если он создан менее чем N секунд назад.

    src/weather/cache.py:

    Что здесь важно:

  • Path(...).stat().st_mtime даёт время последнего изменения файла.
  • json.loads превращает строку JSON в структуры Python.
  • json.dumps делает обратное преобразование.
  • Реализация: CLI и сборка приложения

    src/weather/cli.py:

    Что здесь важно:

  • argparse даёт удобный интерфейс командной строки и автоматическую справку.
  • logging лучше, чем хаотичные print, потому что можно переключать подробность.
  • if __name__ == "__main__" позволяет использовать файл и как скрипт, и как модуль.
  • Запуск

    Если вы запускаете из корня проекта, удобно указать PYTHONPATH, чтобы импорт weather... работал корректно.

    macOS/Linux:

    Windows PowerShell:

    Что вы получаете от таких тестов:

  • уверенность, что формат ответа разбирается корректно
  • возможность менять сетевую часть, не боясь сломать логику разбора
  • Как развивать мини-проект дальше

    Когда базовая версия работает, логичные улучшения такие:

  • добавить поддержку нескольких координат за один запуск
  • сделать кэш раздельным по ключу lat/lon, а не одним файлом
  • сохранить историю запросов в CSV
  • покрыть тестами кэш и CLI через изоляцию зависимостей
  • Итоги

    В этом практическом модуле вы собрали небольшой, но реалистичный проект, где вместе работают ключевые темы курса:

  • виртуальное окружение и установка стороннего пакета через pip
  • модули и организация кода по файлам
  • HTTP-запросы и разбор JSON
  • файлы и кэширование через pathlib
  • исключения и аккуратные сообщения об ошибках
  • автотесты для “чистой” логики через unittest
  • Такой стиль разработки масштабируется: когда проект становится больше, вы просто продолжаете выносить ответственность в отдельные модули и покрывать тестами критичную логику.