Язык программирования Python: основы и практика

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

1. Введение в Python и настройка окружения

Введение в Python и настройка окружения

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

Python — это язык программирования общего назначения, который часто выбирают из-за сочетания простого синтаксиса, большой экосистемы библиотек и широкого применения.

Python используют для:

  • веб-разработки (серверная логика, API)
  • анализа данных и машинного обучения
  • автоматизации и написания скриптов
  • научных вычислений
  • тестирования и DevOps-задач
  • разработки учебных и прототипных проектов
  • Важно понимать базовую идею: вы пишете исходный код (текст программы), а затем Python запускает его через интерпретатор.

    Как Python запускает программы

    Когда вы запускаете файл program.py, работает цепочка:

  • Вы пишете код в текстовом файле.
  • Интерпретатор Python читает ваш код и выполняет его построчно.
  • Результат появляется в терминале (или в виде файлов/сетевых запросов — зависит от программы).
  • У Python есть интерактивный режим — REPL (Read–Eval–Print Loop): вы вводите команду, Python выполняет её сразу и печатает результат. Это удобно для экспериментов.

    !Схема показывает, как исходный код выполняется интерпретатором и чем отличается REPL.

    Версии Python: что ставить

    На практике почти всегда выбирают Python 3. В этом курсе подразумевается Python 3.10+ (подойдёт и более новый, например 3.11 или 3.12).

    Почему это важно:

  • Python 2 давно снят с поддержки
  • современные библиотеки и учебные материалы ориентированы на Python 3
  • Проверить версию можно командами python --version или python3 --version.

    Установка Python

    Windows

  • Скачайте установщик с сайта Python.org.
  • Запустите установщик.
  • Обязательно отметьте галочку Add python.exe to PATH (добавить Python в переменную PATH), чтобы команда python работала в терминале.
  • Завершите установку.
  • Проверка:

  • Откройте PowerShell.
  • Выполните python --version.
  • Если команда не найдена, чаще всего не включён PATH — переустановите Python и поставьте галочку, либо настройте PATH вручную.

    macOS

    В macOS иногда уже есть системный Python, но он может быть не тем, что нужен для разработки. Рекомендуемый вариант для новичка:

  • Скачайте установщик с сайта Python.org.
  • Установите Python.
  • Проверьте в Терминале: python3 --version.
  • Linux

    Во многих дистрибутивах Python уже установлен. Если нет — установите через пакетный менеджер.

    Для Ubuntu/Debian часто подходит:

  • sudo apt update
  • sudo apt install python3 python3-venv python3-pip
  • Проверка: python3 --version
  • Терминал: базовый инструмент разработчика

    Терминал (или командная строка) нужен, чтобы:

  • запускать программы
  • создавать виртуальные окружения
  • устанавливать библиотеки
  • Полезные команды, которые мы будем использовать:

    | Задача | Windows (PowerShell) | macOS/Linux (Terminal) | |---|---|---| | Проверить версию Python | python --version | python3 --version | | Запустить интерактивный режим | python | python3 | | Запустить файл | python main.py | python3 main.py | | Установить пакет | python -m pip install requests | python3 -m pip install requests |

    Обратите внимание на запись python -m pip: это способ запустить pip именно тем Python, который вы используете в проекте (это помогает избежать путаницы, когда Python несколько).

    Редактор кода и IDE

    Вам нужен инструмент, где удобно писать код.

    Варианты:

  • Visual Studio Code (часто выбирают как универсальный вариант) — Visual Studio Code
  • PyCharm Community Edition (IDE, ориентированная на Python) — PyCharm
  • Минимальная рекомендация на старт:

  • установить VS Code
  • поставить расширение Python от Microsoft (VS Code предложит автоматически)
  • Первый запуск: «Hello, world!»

  • Создайте папку проекта, например python-course.
  • Внутри создайте файл hello.py.
  • Напишите код:
  • Запустите из терминала (перейдя в папку проекта):
  • На macOS/Linux, если команда python не работает или запускает не ту версию, используйте:

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

    Виртуальное окружение — это отдельная “копия” Python-настроек для конкретного проекта. Оно позволяет:

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

    Создание и активация venv

  • Создайте окружение (находясь в папке проекта):
  • Активируйте:
  • Windows (PowerShell):

    macOS/Linux:

    Признак успеха: в начале строки терминала обычно появляется (.venv).

  • Чтобы выйти из окружения:
  • Установка библиотек: pip

    pip — это менеджер пакетов Python. С его помощью вы устанавливаете сторонние библиотеки.

    Пример установки библиотеки requests:

    Проверить список установленных пакетов:

    Файл зависимостей requirements.txt

    В реальных проектах зависимости фиксируют в файле requirements.txt, чтобы другой человек (или вы на другом компьютере) мог восстановить окружение.

    Сохранить зависимости:

    Установить зависимости из файла:

    Рекомендуемая структура учебного проекта

    Простой вариант для старта:

  • python-course/ — папка проекта
  • .venv/ — виртуальное окружение (обычно не добавляют в репозиторий)
  • hello.py или main.py — точка входа
  • requirements.txt — зависимости
  • Частые проблемы и как их решать

  • Команда python не найдена: Python не установлен или не добавлен в PATH (особенно на Windows).
  • Ставится пакет, но импорт не работает: пакет установлен не в то окружение. Активируйте .venv и используйте python -m pip ....
  • Несколько Python на компьютере: используйте python3 (macOS/Linux) и всегда проверяйте python --version.
  • Немного про философию Python

    Python ценят за читаемость и ясность кода. Эта идея отражена в “Дзене Python”:

    > Beautiful is better than ugly. > > Explicit is better than implicit. > > Simple is better than complex. > > Readability counts. > > — Tim Peters, The Zen of Python (PEP 20)

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

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

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

    Контекст: как это связано с настройкой окружения

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

    Чтобы практиковаться, создайте файл main.py в папке проекта и запускайте его командой:

    Если у вас macOS/Linux и команда python ведёт не на Python 3, используйте:

    Синтаксис Python: что важно с первого дня

    Отступы вместо фигурных скобок

    В Python блоки кода (например, внутри условий и циклов) задаются отступами, а не {}.

    Пример:

    Правила:

  • Обычно используют 4 пробела на один уровень отступа.
  • Смешивать табы и пробелы не рекомендуется.
  • Двоеточие : в конце строки означает, что дальше начинается блок.
  • Инструкции и выражения

  • Инструкция — команда, которую Python выполняет (например, присваивание x = 10).
  • Выражение — часть кода, которая вычисляется в значение (например, 2 + 2, name.upper()).
  • В Python вы часто будете писать выражения внутри инструкций:

    Комментарии

    Комментарии игнорируются интерпретатором и нужны людям.

  • Однострочный комментарий начинается с #.
  • Стиль кода

    В Python распространён единый стиль оформления. Основной документ — PEP 8. На старте достаточно помнить:

  • имена переменных — snake_case
  • константы (по договорённости) — UPPER_CASE
  • пробелы вокруг операторов — обычно ставят: x = 1 + 2
  • Переменные: имена и присваивание

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

    Переменная — это имя, которое ссылается на объект (значение) в памяти.

    Здесь message — имя, а строка "Привет" — объект.

    !Иллюстрация, что переменная в Python — это ссылка на объект, и ссылка может меняться

    Имена переменных: что можно и что нельзя

    Можно:

  • латинские буквы, цифры и _
  • начинать с буквы или _
  • использовать понятные имена по смыслу
  • Нельзя:

  • начинать с цифры (1name — ошибка)
  • использовать пробелы (user name — ошибка)
  • использовать ключевые слова Python (if, for, class и другие)
  • Присваивание и множественное присваивание

    Обычное присваивание:

    Множественное присваивание:

    Обмен значений местами (без временной переменной):

    Динамическая типизация

    В Python тип принадлежит значению, а не имени переменной. Поэтому одна и та же переменная может начать ссылаться на объект другого типа:

    Это удобно, но требует аккуратности: важно понимать, какой тип данных сейчас в переменной.

    Базовые типы данных

    Официальное описание встроенных типов собрано в документации: Built-in Types.

    Числа: int и float

  • int — целые числа: -3, 0, 42
  • float — числа с дробной частью: 3.14, -0.5
  • Важно:

  • деление / почти всегда даёт float
  • целочисленное деление // отбрасывает дробную часть
  • Логический тип: bool

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

    Пример сравнения:

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

    Строки: str

    Строка — это текст.

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

  • конкатенация (склеивание):
  • длина строки:
  • индексирование (доступ к символам):
  • Важное свойство: строки неизменяемы (нельзя заменить символ по индексу напрямую).

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

    None означает “ничего”, “значение отсутствует”.

    Типичные случаи:

  • переменная объявлена заранее, но значение появится позже
  • функция “ничего не возвращает” (технически возвращает None)
  • Проверка на None обычно делается так:

    Приведение типов

    Иногда нужно преобразовать одно значение в другой тип:

    Важно понимать частую ошибку новичков: строка "10" и число 10 — разные значения.

    Как узнать тип значения

    Используйте type():

    Для проверок “это значение такого-то типа?” часто применяют isinstance():

    Ввод и вывод

    Вывод: print()

    print() печатает данные в терминал:

    Можно печатать несколько значений:

    Ввод: input()

    input() читает строку из терминала. Документация: input.

    Важно: input() всегда возвращает str, даже если вы ввели число. Поэтому обычно нужно преобразование:

    Форматирование строк: f-строки

    Самый удобный способ вставлять значения в строку — f-строки. Они описаны в документации Python: f-strings.

    Преимущества:

  • читаемость
  • меньше ошибок со склеиванием
  • можно вставлять выражения
  • Частые ошибки новичков

  • Забыли отступ или поставили неправильный отступ: Python строго относится к структуре блоков.
  • Путают = и ==:
  • - = — присваивание - == — сравнение
  • Не преобразовали input() в число и пытаются делать арифметику со строкой.
  • Ожидают, что строку можно менять по индексу, как список (это будет ошибкой).
  • Итог

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

  • синтаксис Python и роль отступов
  • переменные как имена, которые ссылаются на объекты
  • базовые типы данных: int, float, bool, str, None
  • ввод/вывод и приведение типов
  • f-строки для удобного форматирования
  • В следующих материалах эти знания будут использоваться постоянно: в условиях, циклах и функциях.

    3. Управляющие конструкции: условия и циклы

    Управляющие конструкции: условия и циклы

    Зачем нужны управляющие конструкции

    В прошлой статье вы научились работать с переменными, типами данных и вводом/выводом. Теперь добавим управление потоком выполнения программы: научимся принимать решения (условия) и повторять действия (циклы). Без этого невозможно писать программы, которые реагируют на ввод пользователя, обрабатывают наборы данных и выполняют действия по шагам.

    В этой статье мы разберём:

  • условный оператор if (включая elif и else)
  • сравнения и логические операторы
  • понятие истинности значений
  • циклы while и for
  • управляющие команды break и continue
  • Документация Python по теме:

  • Условные операторы
  • Циклы for
  • Функция range
  • Команды break и continue
  • Проверка истинности значений
  • Условия: if, elif, else

    Базовая форма if

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

    Ветка else

    else выполняется, если условие в if ложно (False).

    Несколько вариантов: elif

    elif (иначе если) позволяет проверять несколько условий по очереди. Срабатывает первая истинная ветка.

    !Блок-схема показывает, как Python выбирает одну из веток if/elif/else.

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

    Сравнения

    Операторы сравнения возвращают bool, то есть True или False.

    | Оператор | Смысл | Пример | |---|---|---| | == | равно | x == 10 | | != | не равно | x != 10 | | < | меньше | x < 10 | | <= | меньше или равно | x <= 10 | | > | больше | x > 10 | | >= | больше или равно | x >= 10 |

    Важно не путать:

  • = это присваивание
  • == это сравнение
  • Логика: and, or, not

    Логические операторы помогают объединять условия.

  • and истинно, если оба условия истинны
  • or истинно, если истинно хотя бы одно условие
  • not меняет истинность на противоположную
  • Скобки помогают явно задать порядок:

    Истинность значений: что считается True и False

    В условиях можно использовать не только True и False, но и любые значения. Python приводит их к логическому виду по правилам истинности.

    Часто используемые случаи:

  • 0, 0.0 и 0j считаются False
  • пустая строка "" считается False
  • пустые коллекции (например, [], {}, ()) считаются False
  • None считается False
  • почти всё остальное считается True
  • Пример с вводом:

    Здесь условие if text: читается как если строка непустая.

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

    while выполняет блок кода, пока условие остаётся True.

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

    !Схема показывает, что while проверяет условие перед каждой итерацией.

    Типичный шаблон: ввод до корректного значения

    Так часто делают в консольных программах:

    Здесь используется бесконечный цикл while True, который завершается командой break, когда введены корректные данные.

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

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

    Перебор range()

    range() часто используют для повторения действий фиксированное число раз.

  • range(5) даёт числа 0, 1, 2, 3, 4
  • range(2, 6) даёт 2, 3, 4, 5
  • range(1, 10, 2) даёт 1, 3, 5, 7, 9
  • Перебор строки

    Строка это последовательность символов, поэтому её можно перебирать:

    break и continue

    break

    break немедленно завершает цикл.

    continue

    continue пропускает оставшуюся часть тела цикла и переходит к следующей итерации.

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

  • Неправильные отступы в if и циклах: Python воспринимает отступ как структуру программы.
  • Путают = и ==.
  • Забывают обновлять счётчик в while и получают бесконечный цикл.
  • Ожидают, что input() вернёт число: на самом деле он всегда возвращает str, и его нужно преобразовать, например int(...).
  • Пишут слишком сложные условия без скобок: лучше явно группировать логические части.
  • Итог

    Теперь у вас есть базовый набор инструментов для построения логики программы:

  • if/elif/else для ветвления
  • сравнения и логические операторы для построения условий
  • понимание того, какие значения считаются истинными или ложными
  • while для повторения до выполнения условия
  • for и range() для повторения и перебора
  • break и continue для управления поведением цикла
  • Дальше эти конструкции станут основой для более практичных задач: обработки данных, функций и работы со структурами данных.

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

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

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

    Ранее вы научились работать с переменными и типами данных, а также строить логику с помощью if и циклов for/while. Теперь следующий шаг в практике программирования на Python:

  • функции помогают разбивать программу на понятные части и переиспользовать код
  • область видимости объясняет, почему переменные “видны” не везде и как Python ищет имена
  • модули позволяют организовывать проект в несколько файлов и подключать готовые библиотеки
  • Официальные материалы Python по теме:

  • Определение функций
  • Области видимости и пространства имён
  • Модули
  • Функции

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

    Функция решает одну понятную задачу. Это даёт несколько преимуществ:

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

    Как объявить и вызвать функцию

    Функция объявляется с помощью def, далее идут имя, параметры в круглых скобках и двоеточие.

    Правило отступов то же, что и для if и циклов: тело функции начинается после двоеточия и выделяется отступом.

    Параметры и аргументы

  • параметры указываются при объявлении функции
  • аргументы передаются при вызове функции
  • return: что возвращает функция

    return завершает работу функции и отдаёт значение наружу.

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

    Можно задать значение параметра, которое будет использовано, если аргумент не передали.

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

    При вызове можно явно указывать, какой параметр вы заполняете. Это повышает читаемость.

    Основные виды параметров на практике

    | Возможность | Пример | Что даёт | |---|---|---| | Обычные позиционные | f(10, 20) | самый простой вызов | | Значения по умолчанию | def f(x=10): ... | удобные настройки “по умолчанию” | | Именованные аргументы | f(x=10) | читаемость и гибкость порядка | | Произвольное число позиционных | def f(*args): ... | собрать много значений в кортеж | | Произвольное число именованных | def f(**kwargs): ... | собрать пары ключ-значение в словарь |

    Пример с args и *kwargs:

    Докстринги: как документировать функцию

    Докстринг это строка в начале тела функции. Она помогает другим людям (и вам в будущем) понять назначение функции.

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

    Идея области видимости

    Переменная в Python существует в конкретной области видимости. Если коротко:

  • переменные внутри функции обычно локальные и не видны снаружи
  • переменные, объявленные в файле (на верхнем уровне), обычно считают глобальными для этого модуля
  • Как Python ищет имя: правило LEGB

    Когда Python встречает имя (например, value), он ищет его по цепочке:

  • L Local локальная область (внутри текущей функции)
  • E Enclosing область внешней функции (если функции вложены)
  • G Global область модуля (верхний уровень файла)
  • B Built-in встроенные имена (например, len, print)
  • !Диаграмма показывает порядок, в котором Python ищет имена переменных и функций

    Почему изменение глобальной переменной внутри функции часто “не работает”

    Если внутри функции сделать присваивание x = ..., Python считает x локальной переменной этой функции. Поэтому чтение “глобальной” x до присваивания приведёт к ошибке.

    Если действительно нужно изменить глобальную переменную, используют global.

    Практическая рекомендация: старайтесь не строить логику на изменяемых глобальных переменных. Чаще лучше возвращать новое значение через return.

    nonlocal для вложенных функций

    nonlocal нужен, когда есть вложенная функция, и она должна изменить переменную внешней (но не глобальной) функции.

    Модули: как делить программу на файлы

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

    Модуль это обычный файл *.py. Всё, что объявлено на верхнем уровне файла, становится содержимым модуля.

    Например, вы создаёте структуру:

  • project/
  • main.py
  • utils.py
  • Файл utils.py:

    Файл main.py:

    Способы импорта

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

  • import module и обращение через module.name
  • from module import name для точечного импорта
  • import module as alias для псевдонима
  • Что выполняется при импорте

    При первом импорте Python:

  • находит файл модуля
  • выполняет код на верхнем уровне этого файла сверху вниз
  • сохраняет загруженный модуль, чтобы повторный импорт не выполнял всё заново
  • Это важно: если в модуле есть print(...) на верхнем уровне, он сработает при импорте.

    !Схема объясняет, что при import Python выполняет код модуля и затем даёт доступ к его именам

    Зачем нужен блок if __name__ == "__main__":

    Иногда один и тот же файл хочется:

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

    calc.py:

  • если запустить python calc.py, код внутри условия выполнится
  • если сделать import calc, код внутри условия не выполнится
  • Стандартная библиотека Python

    Python поставляется с большим набором модулей. Примеры:

  • math математика
  • random случайные числа
  • datetime даты и время
  • pathlib работа с путями
  • Каталог модулей стандартной библиотеки: Стандартная библиотека Python

    Практический мини-пример: программа с функциями и циклом

    Пример объединяет прошлые темы (ввод, условия, цикл) и текущую (функции).

    Здесь:

  • read_int изолирует проверку ввода и возвращает корректное значение
  • is_even делает одну маленькую проверку и возвращает True или False
  • Частые ошибки новичков

  • Пишут код на верхнем уровне модуля и потом удивляются, что он запускается при import.
  • Путают печать результата и возврат результата: print() показывает текст, return отдаёт значение дальше в программу.
  • Создают функции, которые используют и меняют глобальные переменные, из-за чего поведение становится трудно предсказуемым.
  • Ожидают, что локальная переменная из функции будет доступна снаружи.
  • Итог

    Теперь у вас есть базовые инструменты для написания более крупных программ:

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

    5. Коллекции: списки, кортежи, множества, словари

    Коллекции: списки, кортежи, множества, словари

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

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

    В Python для этого чаще всего используют четыре встроенные коллекции:

  • список list — упорядоченная изменяемая последовательность
  • кортеж tuple — упорядоченная неизменяемая последовательность
  • множество set — неупорядоченный набор уникальных элементов
  • словарь dict — отображение ключ → значение
  • Официальная документация:

  • Встроенные типы данных
  • list
  • tuple
  • set
  • dict
  • Общие идеи: порядок, уникальность, изменяемость

    Коллекции различаются по трём ключевым свойствам:

  • есть ли порядок элементов
  • могут ли элементы повторяться
  • можно ли менять коллекцию после создания
  • Таблица для быстрого выбора:

    | Тип | Порядок | Повторы | Изменяемость | Типичный сценарий | |---|---|---|---|---| | list | есть | можно | да | список задач, результаты измерений | | tuple | есть | можно | нет | фиксированная группа значений | | set | нет (для логики) | нельзя | да | уникальные теги, проверка принадлежности | | dict | есть (сохраняет порядок добавления) | ключи уникальны | да | настройки, таблица данных по ключу |

    !Сравнение коллекций по ключевым свойствам

    Списки list

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

    Список — это упорядоченная последовательность. Элементы нумеруются индексами с нуля.

    Часто список строят из range():

    Изменение списка

    Список изменяемый: можно заменять элементы, добавлять и удалять.

    Полезные методы:

  • append(x) добавить один элемент в конец
  • extend(iterable) добавить сразу много элементов
  • insert(i, x) вставить по индексу
  • remove(x) удалить первое вхождение значения
  • pop(i) удалить и вернуть элемент (по умолчанию последний)
  • sort() отсортировать на месте
  • Пример разницы append и extend:

    Срезы

    Срез позволяет взять часть списка.

    Важно: срез возвращает новый список.

    Перебор списка в цикле

    Если нужен индекс, используйте range(len(...)) (на старте это проще понимать):

    Кортежи tuple

    Что такое кортеж и зачем он нужен

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

    Кортеж часто используют для возвращения нескольких значений из функции:

    Распаковка кортежа

    Кортеж из одного элемента

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

    Множества set

    Идея множества

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

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

    Добавление и удаление

    Проверка принадлежности

    Одна из самых частых причин использовать set — быстрый тест in:

    Операции над множествами

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

  • объединение: a | b
  • пересечение: a & b
  • разность: a - b
  • Словари dict

    Идея словаря

    Словарь хранит пары ключ → значение. По ключу можно быстро получить значение.

    Ключи должны быть неизменяемыми (например, строки, числа, кортежи из неизменяемых элементов). На практике чаще всего используют строки.

    !Как словарь хранит пары ключ-значение и как происходит доступ по ключу

    Добавление, изменение, удаление

    Безопасное чтение: get()

    Если обратиться по отсутствующему ключу через [], будет ошибка. Для безопасного чтения используйте get().

    Проверка ключа через in

    Оператор in для словаря проверяет ключи:

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

    Частые варианты:

  • по ключам
  • по значениям
  • по парам
  • Изменяемость и ссылки: частая ловушка

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

    Если нужен отдельный список-копия, используйте срез или list():

    !Почему b = a не создаёт копию изменяемой коллекции

    Мини-практика: считаем частоты слов

    Этот пример связывает коллекции с функциями и циклами из прошлых тем. Задача: по введённой строке посчитать, сколько раз встречается каждое слово.

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

  • split() превращает строку в список слов
  • counts это словарь: ключ — слово, значение — количество
  • get(w, 0) возвращает текущее значение или 0, если слова ещё нет
  • Как выбрать коллекцию

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

  • нужен упорядоченный набор, который вы будете менять — берите list
  • нужен упорядоченный набор, который менять не надо — берите tuple
  • нужна уникальность и быстрый in — берите set
  • нужно хранить данные по ключу (имя → значение) — берите dict
  • Частые ошибки новичков

  • Пытаться обратиться к элементу множества по индексу: у set нет индексов.
  • Ожидать, что in для словаря проверяет значения: на самом деле он проверяет ключи.
  • Делать b = a и ждать независимую копию списка: это копия ссылки.
  • Использовать изменяемые типы (например, list) как ключи словаря: ключ должен быть неизменяемым.
  • Итог

    Теперь у вас есть базовый набор структур данных Python, на которых строится большая часть прикладного кода:

  • list для упорядоченных изменяемых данных
  • tuple для фиксированных наборов значений
  • set для уникальных элементов и операций над множествами
  • dict для хранения и поиска данных по ключу
  • Дальше эти коллекции будут постоянно использоваться в функциях и модулях: вы будете писать функции обработки списков и словарей, разделять код по файлам и собирать более крупные программы из небольших частей.

    6. Файлы, исключения и работа с данными

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

    Зачем это нужно после коллекций и функций

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

    В этой статье разберём:

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

  • Функция open
  • Исключения
  • pathlib
  • json
  • csv
  • Работа с файлами

    Что такое файл с точки зрения программы

    Файл — это последовательность данных, обычно на диске. Чаще всего на старте вы будете работать с текстовыми файлами:

  • чтение: загрузить текст в программу
  • запись: сохранить результат работы программы
  • Главный инструмент в Python — функция open().

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

    open() возвращает файловый объект, через который можно читать или писать.

    Основные режимы:

    | Режим | Смысл | Если файла нет | Если файл есть | |---|---|---|---| | "r" | чтение | ошибка | читаем | | "w" | запись | создаст | перезапишет | | "a" | добавление в конец | создаст | допишет | | "r+" | чтение и запись | ошибка | читает и пишет |

    Для текстовых файлов обычно указывают encoding="utf-8", чтобы корректно работать с кириллицей.

    Контекстный менеджер with

    Файл важно закрывать. Самый надёжный способ — использовать with: он гарантирует закрытие файла даже при ошибках.

    Если не использовать with, можно забыть закрыть файл, и это приведёт к проблемам: файл может остаться «занятым», данные могут не записаться полностью.

    Чтение файла

    Частые варианты:

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

    rstrip("\n") убирает перевод строки в конце.

    Запись в файл

    Запись — через write(). Важно: write() пишет строку, поэтому числа нужно преобразовать в строку или использовать f-строки.

    Если нужно дописывать (не стирая старое), используйте режим "a".

    Частая ошибка: относительные пути

    Путь "data.txt"относительный. Он считается относительно текущей рабочей директории, из которой вы запускаете программу. Если запускаете проект из разных мест, файл может «не находиться».

    Практика для учебных проектов:

  • хранить данные рядом с main.py
  • использовать pathlib и строить путь относительно файла кода
  • Пути и файлы с pathlib

    Модуль pathlib даёт удобный объект Path вместо ручной работы со строками путей.

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

  • Path.exists() проверить существование
  • Path.mkdir(parents=True, exist_ok=True) создать папки
  • Path.read_text(encoding="utf-8") быстро прочитать текст
  • Path.write_text(text, encoding="utf-8") быстро записать текст
  • Пример: создать папку data и сохранить файл:

    Исключения: что это и зачем

    Идея исключений

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

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

    !Поток выполнения try/except/else/finally

    Базовая обработка: try/except

    Здесь:

  • ValueError возникает, если ввод не преобразуется в int
  • ZeroDivisionError возникает при делении на ноль
  • Универсальный перехват и объект ошибки

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

    OSError — общий класс для многих ошибок ввода-вывода (например, файл не найден, нет прав доступа).

    try/except/else/finally

  • else выполняется, если ошибки не было
  • finally выполняется всегда
  • Когда стоит выбрасывать исключение самому

    Иногда вы хотите явно запретить неверные значения и остановить текущую операцию. Для этого используют raise.

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

    Собственные исключения

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

    Работа с данными: JSON и CSV

    JSON: данные как словари и списки

    JSON — популярный формат обмена данными. Он естественно отображается на структуры Python:

  • объект JSON → dict
  • массив JSON → list
  • строка → str
  • число → int или float
  • true/false → True/False
  • null → None
  • Запись в JSON:

    Чтение из JSON:

    Параметры, которые часто используют:

  • ensure_ascii=False чтобы кириллица сохранялась читаемо
  • indent=2 чтобы файл был красиво отформатирован
  • CSV: таблицы и строки

    CSV — простой формат таблиц: строки и столбцы. В Python удобно использовать модуль csv.

    Запись CSV (через словари):

    Чтение CSV:

    Зачем newline="": это рекомендация документации для корректной работы с переводами строк в CSV, особенно на Windows.

    Мини-пример: чтение файла, обработка ошибок, сохранение результата

    Задача: прочитать файл numbers.txt, где в каждой строке число, пропустить некорректные строки, сохранить сумму в sum.txt.

    Что здесь используется из прошлых тем:

  • функции для разбиения логики (read_numbers)
  • коллекции (список numbers)
  • цикл for и continue
  • словесная диагностика через print
  • Частые ошибки новичков

  • Открывать файл без with и забывать закрывать.
  • Писать в файл и не добавлять \n, ожидая автоматический перевод строки.
  • Ловить исключения слишком широко (except Exception) и «прятать» реальные ошибки.
  • Не указывать encoding="utf-8" и получать проблемы с текстом.
  • Путать текущую папку запуска и папку, где лежит main.py.
  • Итог

    Теперь вы умеете делать то, что превращает учебные программы в прикладные:

  • читать и записывать файлы через open() и with
  • работать с путями через pathlib.Path
  • обрабатывать ошибки с помощью try/except/else/finally
  • сохранять и загружать структурированные данные в JSON
  • работать с табличными данными в CSV
  • Эти навыки постоянно используются в практике: от простых скриптов автоматизации до небольших консольных приложений, которые читают входные данные, обрабатывают их и сохраняют результат.

    7. Основы ООП и тестирование кода

    Основы ООП и тестирование кода

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

    Ранее вы научились:

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

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

    Что такое ООП простыми словами

    Объектно-ориентированное программирование — это стиль, где вы описываете:

  • класс как шаблон
  • объект как конкретный экземпляр этого шаблона
  • Ключевая идея: объект хранит состояние (данные) и умеет выполнять действия (методы).

    Обычно ООП объясняют через несколько принципов:

  • инкапсуляция: прячем детали реализации и даём понятный интерфейс
  • наследование: строим новый класс на основе существующего
  • полиморфизм: разные объекты поддерживают одинаковый интерфейс и взаимозаменяемы в коде
  • В Python важная практическая деталь: полиморфизм часто строится не на строгих типах, а на ожидаемом поведении объекта.

    Классы и объекты в Python

    Определение класса и создание объекта

    Класс объявляется словом class. По соглашению имена классов пишут в стиле PascalCase.

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

  • __init__ — специальный метод, который вызывается при создании объекта
  • self — ссылка на текущий объект, через неё вы читаете и записываете его данные
  • self.name и self.ageатрибуты объекта
  • Документация:

  • Классы в учебнике Python
  • Методы и атрибуты

  • атрибут хранит данные: self.age
  • метод описывает действие: def greet(self): ...
  • Метод почти всегда принимает первым параметром self. При вызове u.greet() Python подставляет self автоматически.

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

    Атрибуты класса принадлежат самому классу и общие для всех экземпляров.

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

  • данные конкретного объекта храните в self.*
  • общие константы и счётчики иногда уместны как атрибуты класса
  • Инкапсуляция: как ограничивают доступ к данным в Python

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

  • name — публичное (обычно можно использовать везде)
  • _nameвнутреннее (не трогайте снаружи без необходимости)
  • __name — имя будет преобразовано интерпретатором так, чтобы снизить риск случайного доступа (механизм name mangling)
  • Свойства через @property

    Если вам нужно:

  • оставить поле “похожим на атрибут”
  • но при этом делать проверку при присваивании
  • используют @property.

    Это связывает тему ООП с прошлой темой про исключения: неверные значения удобно останавливать через raise.

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

  • property
  • Наследование и полиморфизм

    Наследование

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

    Полиморфизм

    Полиморфизм проявляется, когда код работает с разными объектами одинаково, опираясь на общий интерфейс.

    Функции всё равно, Dog это или Cat, пока у объекта есть метод speak.

    super()

    Если вы расширяете поведение родительского класса, часто вызывают super().

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

  • super
  • Специальные методы: делаем объекты удобными

    Специальные методы помогают встроить ваш класс в “язык” Python.

    На старте особенно полезны:

  • __str__ — “человекочитаемая” строка
  • __repr__ — строка для отладки, желательно однозначная
  • dataclass: быстрый способ описывать “структуры данных”

    Если класс в основном хранит данные (как словарь, но с полями), удобно использовать dataclasses.

    Что даёт @dataclass:

  • автоматически создаёт __init__
  • даёт аккуратный __repr__
  • уменьшает количество шаблонного кода
  • Документация:

  • dataclasses
  • Тестирование кода: зачем оно нужно

    Тестирование отвечает на вопрос: не сломали ли мы уже работающий код?

    Хорошие тесты помогают:

  • уверенно менять код (рефакторинг)
  • быстрее находить ошибки
  • фиксировать требования в виде проверок
  • На старте вам достаточно юнит-тестов: они проверяют маленькие части программы (функции и методы) изолированно.

    Практический совет: чем меньше в функции ввода/вывода (файлы, сеть, input()), тем проще её тестировать.

    !Пирамида тестирования и место юнит-тестов

    unittest: тестирование стандартной библиотекой

    Модуль unittest встроен в Python, поэтому ничего ставить не нужно.

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

  • unittest
  • Минимальная структура теста

    Файл calc.py:

    Файл test_calc.py:

    Запуск:

    Проверка исключений

    pytest: популярная альтернатива (по желанию)

    pytest часто выбирают за более короткий синтаксис.

  • установка в активированное окружение:
  • запуск:
  • Документация:

  • pytest
  • Пример теста для pytest:

    Практический пример: класс и тесты к нему

    Сделаем небольшой класс без файлов и без input(), чтобы его было легко тестировать.

    Файл todo.py:

    Файл test_todo.py для unittest:

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

  • коллекции: внутри класса список словарей
  • исключения: ошибки сигнализируются через ValueError и IndexError
  • модули: класс лежит в todo.py, тесты импортируют его
  • Итог

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

  • создавать классы, объекты, атрибуты и методы
  • использовать __init__, self, @property, наследование, super()
  • применять специальные методы __str__ и __repr__ для удобства отладки
  • писать базовые юнит-тесты на unittest и проверять исключения
  • при желании использовать pytest в виртуальном окружении
  • Эти навыки обычно идут вместе: ООП помогает строить понятные компоненты, а тесты защищают их поведение при изменениях.