Основы языка программирования Python 3

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

1. Введение в Python 3: установка, запуск, синтаксис и стиль

Введение в Python 3: установка, запуск, синтаксис и стиль

Что такое Python 3 и где он используется

Python 3 — это язык программирования общего назначения, который ценят за читаемый синтаксис, богатую стандартную библиотеку и огромную экосистему пакетов.

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

  • автоматизации задач и написании скриптов
  • анализе данных и машинном обучении
  • веб-разработке
  • тестировании
  • создании консольных утилит и небольших приложений
  • В этом курсе мы будем писать код на Python 3, запускать его из терминала и постепенно разберём базовые конструкции языка.

    Установка Python 3

    Проверка: установлен ли Python

    Перед установкой полезно проверить, есть ли Python в системе.

    В терминале (macOS/Linux) или PowerShell (Windows) выполните:

    Если команда не найдена или версия слишком старая, установите Python.

    > В разных системах команда может быть python3 вместо python. Мы будем ориентироваться на то, что у вас работает хотя бы одна из них.

    Установка на Windows

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

    Установка на macOS

    Рекомендуемый способ — официальный установщик:

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

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

    Проверка:

    Редактор кода и терминал

    Python-код можно писать в любом текстовом редакторе, но удобнее использовать среду с подсветкой синтаксиса, подсказками и встроенным терминалом.

    Популярный вариант:

  • Visual Studio Code
  • расширение Python extension for Visual Studio Code
  • Первый запуск Python

    Интерактивный режим (REPL)

    REPL — это режим, где вы вводите команды построчно и сразу видите результат. Запуск:

    или:

    Пример:

    Выйти обычно можно командой:

    REPL удобен для быстрых проверок, но основной код мы будем хранить в файлах.

    Запуск файла .py

    Создайте файл hello.py с таким содержимым:

    Запустите из папки с файлом:

    или:

    !Схема показывает путь: написать код в .py → запустить командой → увидеть вывод

    Пакеты, pip и виртуальные окружения

    Что такое пакет

    Пакет — это готовая библиотека, которую можно подключить к проекту, чтобы не писать всё с нуля (например, для работы с HTTP, таблицами, графиками).

    pip

    pip — стандартный менеджер пакетов Python. Справка и документация: pip documentation

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

    Установка пакета (пример):

    Зачем нужно виртуальное окружение

    Виртуальное окружение — это отдельная папка с собственной установкой зависимостей (пакетов) для конкретного проекта. Это помогает:

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

    Активация:

  • Windows (PowerShell)
  • macOS/Linux
  • Документация: venv — Creation of virtual environments

    Базовый синтаксис Python: самое важное

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

    В Python блоки кода задаются отступами, а не {}. Обычно используется 4 пробела.

    Пример (обратите внимание на отступ):

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

    Комментарии

    Однострочный комментарий начинается с #:

    Переменные и типы данных

    В Python тип обычно определяется автоматически:

    Полезные функции:

  • type(x) — узнать тип
  • int("123"), float("1.5"), str(10) — преобразования
  • Вывод на экран

    Ввод пользователя

    Важно: input() всегда возвращает строку. Если нужно число:

    Строки и f-строки

    Строки можно складывать, умножать, брать длину:

    Удобный способ форматировать строки — f-строки:

    Ошибки и чтение сообщений

    Ошибки — нормальная часть разработки. Важно научиться читать сообщение:

  • где ошибка (файл и строка)
  • что произошло (тип ошибки)
  • Пример типичной ошибки отступов:

    Python сообщит об ошибке, потому что ожидает отступ внутри блока if.

    Стиль кода: как писать по-питоновски

    Хороший стиль делает код понятным вам и другим.

    PEP 8

    Основной документ по стилю Python — PEP 8.

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

  • отступ: 4 пробела
  • имена переменных и функций: lower_snake_case
  • имена классов: UpperCamelCase
  • константы (по договорённости): UPPER_SNAKE_CASE
  • пробелы вокруг операторов: a = b + c, а не a=b+c
  • Пример: «плохо» и «хорошо»

    Плохо:

    Лучше:

    Автоформатирование

    Когда проектов станет больше, полезно подключать автоформаттеры и линтеры. Например, форматтер Black: Black documentation

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

    Итоги

    В этой статье вы:

  • установили Python 3 и проверили версию
  • узнали, как запускать Python в REPL и как запускать файлы .py
  • познакомились с pip и виртуальными окружениями venv
  • разобрали основы синтаксиса: отступы, комментарии, переменные, ввод/вывод, строки
  • узнали базовые правила стиля PEP 8
  • Дальше мы начнём писать более содержательные программы и разберём основные типы данных и операции с ними.

    2. Типы данных и операции: числа, строки, булевы значения, ввод-вывод

    Типы данных и операции: числа, строки, булевы значения, ввод-вывод

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

    Типы данных: что хранится в переменных

    Тип данных определяет:

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

  • int — целые числа
  • float — числа с дробной частью
  • str — строки (текст)
  • bool — булевы значения True/False
  • Посмотреть тип можно функцией type():

    Официальная справка по встроенным типам: Built-in Types

    Числа: int и float

    Создание и базовые операции

    Числа создаются напрямую:

    Основные арифметические операции:

    | Операция | Пример | Результат | Комментарий | |---|---|---|---| | Сложение | 5 + 2 | 7 | | | Вычитание | 5 - 2 | 3 | | | Умножение | 5 * 2 | 10 | | | Деление | 5 / 2 | 2.5 | всегда даёт float | | Целочисленное деление | 5 // 2 | 2 | без дробной части | | Остаток от деления | 5 % 2 | 1 | полезно для проверки чётности | | Степень | 5 ** 2 | 25 | |

    Пример:

    Порядок выполнения операций

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

  • сначала **
  • затем *, /, //, %
  • затем +, -
  • Скобки помогают явно задать порядок:

    Полезные функции для чисел

  • abs(x) — модуль числа
  • round(x, n) — округление до n знаков после запятой
  • > Из-за особенностей хранения float некоторые дроби представляются приближённо. Это нормально: 0.1 + 0.2 может дать 0.30000000000000004. Для обучения достаточно помнить, что floatприближённый тип.

    Строки: str

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

    Склейка, повторение, длина

    | Действие | Пример | Результат | |---|---|---| | Склейка | "Py" + "thon" | "Python" | | Повторение | "ha" * 3 | "hahaha" | | Длина | len("abc") | 3 |

    Индексация (полезный минимум)

    У строки можно взять символ по индексу. Индексы начинаются с 0:

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

    Если индекс выходит за границы, будет ошибка IndexError.

    Преобразования между строками и числами

    Очень частая ситуация: у вас есть число, но оно хранится как строка (например, из input()). Тогда нужны преобразования:

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

    Документация по строкам: str

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

    Самый удобный способ собрать строку из текста и значений — f-строка:

    Булевы значения: bool

    Тип bool имеет два значения:

  • True
  • False
  • Они появляются:

  • как результат сравнений
  • при логических операциях
  • Сравнения

    | Сравнение | Значение | |---|---| | == | равно | | != | не равно | | <, <= | меньше, меньше или равно | | >, >= | больше, больше или равно |

    Примеры:

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

    | Оператор | Смысл | Пример | |---|---|---| | and | и (оба условия истинны) | age >= 18 and has_ticket | | or | или (хотя бы одно истинно) | is_admin or is_moderator | | not | не (инверсия) | not is_blocked |

    Документация по булевому типу: bool

    Ввод и вывод: input() и print()

    print() — вывод

    print() выводит значения на экран.

    Полезные параметры:

  • sep — разделитель между аргументами
  • end — что добавить в конце (по умолчанию перевод строки)
  • Документация: print

    input() — ввод

    input() читает строку с клавиатуры и всегда возвращает str:

    Если нужно число, необходимо преобразование:

    !Схема показывает, что input() всегда возвращает строку и часто требуется преобразование типа

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

    Типичные ошибки новичка и как их распознавать

  • Сложение строки и числа:
  • Правильно так:

  • Забыли, что input() возвращает строку:
  • Нужно:

    Итоги

    Теперь вы знаете:

  • чем отличаются int, float, str, bool
  • какие арифметические операции доступны в Python и как работает порядок вычислений
  • как работать со строками: склейка, повторение, длина, индексация, f-строки
  • как получать bool через сравнения и комбинировать условия через and, or, not
  • как правильно использовать input() и print() и когда нужно преобразование типов
  • 3. Коллекции: списки, кортежи, множества и словари

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

    В прошлых статьях вы узнали про базовые типы (int, float, str, bool) и операции над ними, а также про print() и input(). Но реальная программа почти всегда работает не с одним значением, а с набором значений: списком товаров, набором уникальных тегов, таблицей настроек. Для этого в Python есть коллекции.

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

    Какие коллекции есть в Python

    Четыре самых важных встроенных коллекции:

    | Коллекция | Как выглядит | Порядок элементов | Можно менять после создания | Особенность | |---|---|---|---|---| | list (список) | [1, 2, 3] | да | да | универсальная коллекция | | tuple (кортеж) | (1, 2, 3) | да | нет | защищает данные от изменений | | set (множество) | {1, 2, 3} | нет | да | хранит только уникальные элементы | | dict (словарь) | {"a": 1, "b": 2} | да | да | хранит пары ключ → значение |

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

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

    Списки: list

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

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

    Индексация и срезы

    Индексы начинаются с 0:

    Срез берёт часть списка:

    Изменение элементов

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

    Частые методы списков

    | Метод | Что делает | Пример | |---|---|---| | append(x) | добавить элемент в конец | lst.append(5) | | extend(items) | добавить сразу много элементов | lst.extend([1, 2]) | | pop() | удалить и вернуть элемент (по умолчанию последний) | x = lst.pop() | | remove(x) | удалить первый найденный x | lst.remove(20) | | sort() | отсортировать список | lst.sort() |

    Пример:

    Полезные операции со списками

    len() и оператор in вы уже встречали со строками: для коллекций они тоже работают.

    Ввод данных и списки

    input() возвращает строку, и часто нужно превратить её в список значений. Простой пример: пользователь вводит слова через пробел.

    > split() возвращает список строк. Это удобно для простой обработки ввода.

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

    Кортежи: tuple

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

    Создание кортежа

    Если элемент один, нужна запятая:

    Чем полезна неизменяемость

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

    При этом кортеж можно читать так же, как список:

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

    Множества: set

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

    Создание множества

    Важно: пустое множество создаётся так:

    А {} — это пустой словарь, а не множество.

    Уникальность и проверка наличия

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

    Множества удобны, когда нужно находить пересечения и объединения наборов:

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

    Словари: dict

    Словарь хранит пары ключ → значение. Он нужен, когда вы хотите быстро получать значение по ключу: настройки, цены, данные пользователя.

    Создание словаря

    Доступ по ключу

    Если ключа нет, user["city"] вызовет KeyError. Более безопасный способ — get():

    Изменение словаря

    Ключи и значения

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

    > keys() и values() возвращают специальные представления. Их можно превратить в список через list(...).

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

    Важное понятие: изменяемые и неизменяемые типы

    Коллекции отличаются тем, можно ли изменить объект после создания:

  • изменяемые: list, set, dict
  • неизменяемые: tuple, а также базовые типы вроде int, str, bool
  • Почему это важно: если две переменные ссылаются на один и тот же изменяемый объект, изменение через одну переменную будет видно через другую.

    Если нужен независимый список, можно сделать копию:

    Как выбрать подходящую коллекцию

    Ориентируйтесь на задачу:

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

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

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

    4. Управление потоком: условия, циклы, match-case и генераторы

    Управление потоком: условия, циклы, match-case и генераторы

    В предыдущих статьях вы научились работать с типами данных (int, float, str, bool) и коллекциями (list, tuple, set, dict). Теперь пора научиться управлять тем, когда и сколько раз выполняется код. Это и есть управление потоком выполнения.

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

  • условия if/elif/else
  • циклы for и while, а также break и continue
  • конструкцию match-case (Python 3.10+)
  • генераторы и yield для эффективной работы с последовательностями
  • Основной справочный раздел в документации: Control Flow Tools

    !Схема показывает, как выбирается одна из веток в if/elif/else

    Условия: if, elif, else

    Условие позволяет выполнить код только если выражение истинно.

    Базовый синтаксис

    Важно:

  • после условия стоит двоеточие :
  • блок кода определяется отступом (обычно 4 пробела)
  • условие должно возвращать bool (или значение, которое можно интерпретировать как True/False)
  • Несколько веток: elif

    Python проверяет ветки сверху вниз и выполняет первую подходящую.

    Вложенные условия

    Условия можно вкладывать друг в друга:

    Если вложенность становится большой, часто можно упростить код с помощью логических операторов and/or.

    Частая ошибка: сравнение вместо присваивания

  • = — присваивание
  • == — сравнение
  • Неправильно:

    Правильно:

    Тернарный оператор (условное выражение)

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

    Это выражение читается как: значение слева, если условие истинно, иначе значение справа.

    Циклы: повторение действий

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

    for: перебор элементов

    Цикл for в Python работает как перебор элементов последовательности.

    #### Перебор списка

    #### range() для повторений

    range(n) создаёт последовательность чисел от 0 до n - 1.

    Частые формы:

  • range(5)0..4
  • range(2, 6)2..5
  • range(10, 0, -2)10, 8, 6, 4, 2
  • while: повторять, пока условие истинно

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

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

    Управление циклом: break, continue, else

    break: досрочно выйти из цикла

    continue: пропустить текущую итерацию

    else у циклов

    В Python у циклов бывает else. Он выполняется, если цикл завершился без break.

    Здесь else означает: не нашли причину прервать цикл.

    Практичные инструменты для перебора

    enumerate() — индекс и элемент

    Когда нужен и индекс, и значение:

    zip() — параллельный перебор

    Если списки разной длины, zip() остановится на самом коротком.

    match-case: структурное сопоставление (Python 3.10+)

    match-case — конструкция, которая помогает удобно разбирать варианты значения (и не только значения).

    Справка: The match statement

    Простой пример (замена цепочки if/elif)

    Особенности:

  • _ — шаблон по умолчанию (как else)
  • case сравнивает не через == буквально во всех случаях, а через правила сопоставления (pattern matching)
  • Сопоставление с несколькими вариантами

    Сопоставление со структурами (кортежи и списки)

    Это особенно полезно вместе с коллекциями из прошлой статьи.

    Здесь x и y — это переменные-шаблоны: если форма подходит, Python присваивает им соответствующие значения.

    > Если у вас Python ниже 3.10, match-case не будет работать. Проверить версию можно командой python --version.

    Генераторы: ленивые последовательности и yield

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

    Идея генератора:

  • он не создаёт сразу всю коллекцию
  • он выдаёт значения по одному, по мере запроса
  • Генераторное выражение

    Похоже на создание списка, но в круглых скобках:

    Справка: Generator expressions

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

    Разница практическая:

  • список хранит все элементы
  • генератор выдаёт элементы по одному
  • Генераторная функция и yield

    Генератор можно написать как функцию, которая использует yield вместо return.

    Что происходит:

  • yield возвращает очередное значение наружу
  • выполнение функции приостанавливается
  • при следующем запросе значения функция продолжается с того места
  • Справка: Yield expressions

    Где генераторы особенно полезны

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

    Итоги

    Теперь вы умеете управлять выполнением программы:

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

    5. Функции: параметры, области видимости, lambda, рекурсия

    Функции: параметры, области видимости, lambda, рекурсия

    В прошлых темах вы изучили типы данных, коллекции и управление потоком (if, циклы, match-case). Следующий шаг — научиться упаковывать логику в переиспользуемые блоки кода. Для этого в Python есть функции.

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

  • не дублировать код
  • делать программу понятнее (давать действиям имена)
  • тестировать и изменять части программы отдельно
  • Официальная справка: Defining Functions

    Что такое функция и как её объявлять

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

    Синтаксис def, return

    Ключевые моменты:

  • def greet(name): объявляет функцию greet с параметром name
  • тело функции — блок с отступом
  • return возвращает значение вызывающему коду и завершает функцию
  • Если return не указан, функция возвращает None:

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

    Внутри функции часто пишут докстроку — строку в тройных кавычках первой строкой тела функции.

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

  • параметры — переменные в объявлении функции
  • аргументы — конкретные значения при вызове
  • Позиционные и именованные аргументы

    Позиционный вызов:

    Именованный (keyword) вызов:

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

    Параметру можно задать значение по умолчанию. Тогда аргумент можно не передавать.

    #### Важное правило про изменяемые значения по умолчанию

    Не задавайте в качестве значения по умолчанию изменяемые объекты (list, dict, set). Такой объект создаётся один раз и будет общим для всех вызовов.

    Плохо:

    Правильно:

    Произвольное число аргументов: args и *kwargs

    *args собирает лишние позиционные аргументы в кортеж:

    **kwargs собирает лишние именованные аргументы в словарь:

    Вместе:

    > Порядок параметров в объявлении важен: обычно используют def f(a, b=0, args, *kwargs): ....

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

    Переменные существуют внутри областей видимости.

    Главная идея:

  • переменные, созданные внутри функции, локальные для этой функции
  • снаружи их не видно
  • внутри функции можно читать внешние переменные, но присваивание создаёт локальную переменную (если не указать иначе)
  • !Порядок, в котором Python ищет переменную по имени

    Локальные и глобальные переменные

    Если внутри функции только читать глобальную переменную — проблем нет:

    Но если вы попытаетесь присвоить x внутри функции, Python посчитает x локальной, и чтение до присваивания вызовет ошибку:

    Ключевое слово global

    global говорит: “используй глобальную переменную, а не создавай локальную”.

    Справка: The global statement

    > В учебных задачах global иногда удобен, но в реальных проектах обычно предпочитают возвращать значения из функций и хранить состояние в структурах данных.

    Вложенные функции и nonlocal

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

    Справка: The nonlocal statement

    lambda: маленькие функции “на месте”

    lambda создаёт короткую безымянную функцию-выражение.

    Справка: Lambda expressions

    Пример:

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

    lambda как ключ сортировки

    Пусть есть список словарей (это сочетание коллекций из прошлых тем):

    Здесь key — функция, которая для каждого элемента возвращает “ключ сравнения”.

    Когда лучше не использовать lambda

  • если логика больше одной простой операции
  • если нужна читаемость и возможность переиспользовать
  • Тогда лучше написать обычную def-функцию с именем.

    Рекурсия: функция вызывает саму себя

    Рекурсия — это подход, при котором задача решается через решение “такой же, но меньшей” задачи.

    Чтобы рекурсия работала правильно, нужны две части:

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

    Пример: факториал

    Факториал (читается “эн факториал”) — это произведение чисел от 1 до . Например, для 4 это .

    Рекурсивная реализация:

    Почему это работает:

  • для n == 1 (или 0) мы точно знаем ответ: 1
  • для n > 1 сводим задачу к меньшей: factorial(n - 1)
  • Рекурсия и ограничения

    У рекурсии есть ограничение: слишком глубокая рекурсия приведёт к ошибке RecursionError. Лимит можно посмотреть и менять через модуль sys, но для обучения важнее понимать принцип и выбирать подходящий метод.

    Справка: sys.setrecursionlimit

    Когда рекурсия уместна

  • деревья и вложенные структуры (например, вложенные списки)
  • задачи “разделяй и властвуй”
  • алгоритмы обхода (позже в обучении)
  • Во многих бытовых задачах рекурсию можно заменить циклом for или while, и цикл будет проще.

    Как сочетать функции с условиями и коллекциями

    Функции особенно полезны, когда вы обрабатываете коллекции и используете ветвления/циклы.

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

    В таком виде код:

  • легко читать
  • легко переиспользовать
  • легко тестировать на разных входных данных
  • Итоги

    В этой теме вы изучили:

  • как объявлять функции через def, возвращать значения через return и писать докстроки
  • как работают параметры: позиционные/именованные аргументы, значения по умолчанию, args и *kwargs
  • что такое области видимости, и когда нужны global и nonlocal
  • как использовать lambda для коротких функций, особенно в sorted(..., key=...)
  • что такое рекурсия, зачем нужен базовый случай и какие у рекурсии ограничения
  • 6. Модули и пакеты: импорт, виртуальные окружения, pip, стандартная библиотека

    Модули и пакеты: импорт, виртуальные окружения, pip, стандартная библиотека

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

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

  • что такое модуль и пакет
  • как работает import
  • как Python находит импортируемые модули
  • зачем нужны виртуальные окружения venv
  • как устанавливать зависимости через pip
  • что полезного есть в стандартной библиотеке
  • !Схема показывает связь: структура модулей, импорт и установка зависимостей в виртуальное окружение

    Модуль и пакет: базовые понятия

    Модуль

    Модуль в Python — это один файл с кодом, обычно с расширением .py.

    Пример: файл math_utils.py — это модуль math_utils.

    Пакет

    Пакет — это папка с Python-кодом, которую можно импортировать как единое целое.

    Классический вариант пакета содержит файл __init__.py.

    Пример структуры:

    Здесь utils — пакет, а utils.math_utils — модуль внутри пакета.

    > Термин пакет встречается в двух смыслах. > >- Python-пакет в проекте — папка с модулями (например, utils). >- Пакет на PyPI — библиотека, которую ставят через pip (например, requests). > > Это разные вещи, хотя часто связаны: пакет на PyPI внутри содержит Python-пакеты и модули.

    Справка: Модули в Python

    Импорт: как подключать код

    Импорт модуля целиком

    Здесь импортируется модуль math из стандартной библиотеки, а доступ к функциям идёт через префикс math..

    Импорт конкретных имён

    Так короче, но есть риск конфликтов имён, если в программе появится sqrt из другого места.

    Псевдонимы (alias)

    Псевдонимы используют, чтобы:

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

    Файлы:

    helpers.py:

    main.py:

    Важно: запускать main.py нужно из папки project, чтобы Python видел helpers.py рядом.

    Как Python находит модули: sys.path

    Когда вы пишете import something, Python ищет модуль примерно по такой логике:

  • встроенные модули
  • пути из переменной окружения PYTHONPATH (если задана)
  • список путей в sys.path (включая текущую папку запуска и site-packages окружения)
  • Посмотреть, где Python ищет модули:

    Если вы видите ошибки ModuleNotFoundError, обычно причина одна из этих:

  • вы запускаете файл не из той папки
  • модуль не установлен в текущее окружение
  • в проекте есть файл с именем, конфликтующим со стандартным модулем (например, random.py рядом с вашим кодом)
  • Справка: Модуль sys

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

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

    utils/text.py:

    main.py:

    Зачем __init__.py

    Файл __init__.py делает папку пакетом в классическом смысле и позволяет:

  • импортировать пакет
  • выполнять код инициализации пакета
  • управлять тем, что считается публичным API пакета
  • На современных версиях Python существуют пространства имён пакетов без __init__.py, но для обучения и большинства обычных проектов проще придерживаться привычной схемы с __init__.py.

    Справка: Пакеты

    __name__ == "__main__": как писать модули, которые можно запускать

    У каждого модуля есть специальная переменная __name__:

  • если файл импортирован, __name__ обычно равен имени модуля
  • если файл запущен напрямую, __name__ равен строке "__main__"
  • Пример tools.py:

    Теперь:

  • import tools не запустит печать приветствия
  • python tools.py запустит код внутри блока if __name__ == "__main__":
  • Это удобный шаблон, чтобы:

  • хранить функции в модуле
  • иметь небольшой демонстрационный запуск или ручной тест
  • Справка: Что такое "главной" модуль

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

    В прошлой статье вы уже создавали venv. Теперь закрепим, почему это критично.

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

    Оно решает типичные проблемы:

  • разные проекты требуют разные версии одной библиотеки
  • зависимости не засоряют системный Python
  • проще повторить окружение на другом компьютере
  • Создание и активация venv

    Создать окружение в папке проекта:

    Активация:

  • Windows (PowerShell)
  • macOS/Linux
  • После активации команды python и pip (обычно) относятся именно к окружению .venv.

    Справка: venv — виртуальные окружения

    pip и PyPI: установка библиотек

    Что такое PyPI

    PyPI (Python Package Index) — официальный каталог пакетов Python.

    Сайт: PyPI

    Почему полезно запускать pip так: python -m pip

    Одна из частых проблем новичков: в системе несколько Python, и pip может указывать не на тот интерпретатор.

    Более надёжно:

    Так вы явно используете pip, связанный с текущим python.

    Справка: pip documentation

    Установка, обновление, удаление

    Установить пакет:

    Обновить пакет:

    Удалить пакет:

    Фиксация зависимостей: requirements.txt

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

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

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

    > Для учебных проектов pip freeze подходит. В больших проектах часто используют более строгие инструменты управления зависимостями, но на старте это не обязательно.

    Стандартная библиотека: что можно не устанавливать

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

    Индекс стандартной библиотеки: The Python Standard Library

    Ниже несколько модулей, которые особенно полезны на старте.

    pathlib: удобная работа с путями и файлами

    pathlib удобнее, чем ручная склейка строк, и корректно работает на разных ОС.

    Справка: pathlib

    datetime: даты и время

    Справка: datetime

    json: чтение и запись JSON

    Справка: json

    random: случайные числа

    Справка: random

    re: регулярные выражения

    Справка: re

    os и sys: взаимодействие с системой и интерпретатором

    Справка: os

    Типовые проблемы с импортами и как их избегать

  • Конфликт имён
  • Не называйте свои файлы как модули стандартной библиотеки: json.py, sys.py, random.py.
  • Запуск “не оттуда”
  • Если main.py импортирует utils, обычно нужно запускать из корня проекта, например так: python main.py в папке project.
  • Забыли активировать окружение
  • Если пакет установлен, но импорт не работает, проверьте, что активировано нужное .venv.
  • Смешали разные Python
  • Если не уверены, используйте python -m pip ... вместо pip ....
  • Итоги

    Теперь вы понимаете, как устроены зависимости и структура Python-проектов:

  • модуль — это файл .py, пакет — папка с модулями
  • import подключает код, а Python ищет модули по путям из sys.path
  • if __name__ == "__main__": помогает писать модули, которые можно и импортировать, и запускать
  • виртуальные окружения venv изолируют зависимости проектов
  • pip устанавливает библиотеки из PyPI, а requirements.txt помогает воспроизводить окружение
  • стандартная библиотека часто закрывает базовые потребности без внешних установок
  • 7. Исключения и основы ООП: классы, объекты, методы, наследование

    Исключения и основы ООП: классы, объекты, методы, наследование

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

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

    Когда во время выполнения происходит проблема (например, деление на ноль или неверный индекс), Python выбрасывает исключение (exception) и обычно останавливает программу.

    Пример:

    Если пользователь введёт 0, программа завершится с ошибкой ZeroDivisionError.

    Справка: Ошибки и исключения

    Зачем обрабатывать исключения

    Обработка исключений нужна, чтобы:

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

    Конструкция try-except

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

    Как это читается:

  • try содержит код, где может произойти ошибка
  • except ... ловит конкретный тип исключения
  • else выполняется, если ошибок не было
  • finally выполняется всегда (даже если была ошибка или был return)
  • !Блок-схема показывает, какие части выполняются при ошибке и без ошибки

    Как правильно выбирать, что ловить

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

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

    Так вы можете незаметно скрыть действительно важную ошибку.

    Ловить несколько исключений одним блоком

    Можно указать кортеж типов:

    Как устроены исключения: базовая иерархия

    Почти все стандартные ошибки в Python наследуются от Exception.

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

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

    raise: как создавать ошибку самому

    Иногда вы хотите явно остановить выполнение, если входные данные неверные.

    Пример:

    Здесь raise ValueError(...) создаёт исключение, которое можно обработать выше.

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

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

    Свой тип исключения обычно наследуют от Exception.

    Основы ООП: класс и объект

    ООП в Python строится вокруг двух идей:

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

    Справка: Классы

    Как объявить класс и создать объект

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

    Атрибуты и методы

  • атрибут это данные объекта (например, имя)
  • метод это функция, привязанная к объекту (например, поприветствовать)
  • self: ссылка на текущий объект

    В методах первым параметром пишут self. Это ссылка на тот объект, у которого вызвали метод.

    Пример:

    Здесь:

  • self.name создаёт или меняет атрибут объекта
  • u.greet() автоматически передаёт u как self
  • __init__: конструктор (инициализация)

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

    Важно:

  • __init__ вызывается при создании объекта: User(...)
  • __init__ ничего не возвращает (обычно)
  • Атрибуты экземпляра и атрибуты класса

    Есть два уровня данных:

  • атрибут экземпляра хранится в конкретном объекте (self.name)
  • атрибут класса общий для всех объектов
  • Пример:

    Если вы сделаете self.created = ..., вы создадите атрибут экземпляра, который может “перекрыть” атрибут класса. На старте держите правило:

  • общие настройки и константы кладём в класс
  • состояние конкретного объекта кладём в self
  • Полезные магические методы: __repr__ и __str__

    Чтобы объект было удобно печатать, добавляют:

  • __repr__ для “технического” представления
  • __str__ для “человеческого” текста
  • Пример:

    Справка: Модель данных Python

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

    Наследование нужно, когда есть “общая” часть поведения и “частные” различия.

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

    Здесь Dog и Cat:

  • наследуют атрибут name и __init__ от Animal
  • переопределяют speak
  • super(): как вызвать логику базового класса

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

    super().__init__(name) вызывает __init__ базового класса User.

    Композиция против наследования

    Не всё нужно делать наследованием. Иногда лучше композиция: объект хранит другой объект и делегирует ему работу.

    Простой ориентир:

  • наследование: “является” (Dog является Animal)
  • композиция: “имеет” (Car имеет Engine)
  • На старте достаточно научиться узнавать эти ситуации, чтобы не делать наследование там, где оно только усложнит код.

    Как исключения сочетаются с ООП

    Частая практика: классы проверяют входные данные и выбрасывают исключения, если состояние объекта будет некорректным.

    Пример:

    Здесь исключения помогают:

  • не допустить “ломаное” состояние объекта
  • сообщить вызывающему коду понятную причину отказа
  • Итоги

    В этой статье вы освоили две важные опоры практического Python:

  • как работают исключения, как использовать try/except/else/finally, когда применять raise и как создавать свои исключения
  • основы ООП: что такое класс и объект, как устроены атрибуты и методы, зачем нужен self и __init__, чем отличаются атрибуты класса от атрибутов экземпляра
  • наследование, переопределение методов и использование super()
  • Эти темы особенно важны дальше, когда вы начнёте писать более крупные программы, собирать проект из нескольких модулей и строить понятные модели данных.