Python: От новичка до профессионала

Этот курс проведет вас от самых основ синтаксиса Python до продвинутых концепций разработки и архитектуры приложений. Вы освоите структуры данных, объектно-ориентированное программирование и научитесь писать эффективный и чистый код.

1. Введение в Python: установка окружения, переменные и базовые алгоритмические конструкции

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

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

Почему именно Python? Он обладает простым и читаемым синтаксисом, который максимально приближен к обычному английскому языку. Это позволяет новичкам сосредоточиться на изучении логики программирования, а не на борьбе со сложными скобками и запятыми.

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

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

Прежде чем писать код, нам нужно установить инструменты. Программисту требуются две основные вещи:

  • Интерпретатор Python — программа, которая читает ваш код и выполняет его.
  • Редактор кода (IDE) — удобная программа, где вы будете писать этот код.
  • !Как ваш код превращается в действия компьютера: редактор передает текст интерпретатору, а тот дает команды процессору.

    Шаг 1: Установка Python

  • Перейдите на официальный сайт python.org.
  • Скачайте последнюю версию для вашей операционной системы (Windows или macOS).
  • Важно: При запуске установщика обязательно поставьте галочку напротив пункта Add Python to PATH (Добавить Python в переменную среды). Если этого не сделать, запускать программы будет сложнее.
  • Нажмите «Install Now» и дождитесь окончания установки.
  • Шаг 2: Установка редактора кода

    Вы можете писать код хоть в «Блокноте», но это неудобно. Мы рекомендуем использовать Visual Studio Code (VS Code) — это бесплатный, легкий и мощный редактор.

  • Скачайте VS Code с официального сайта code.visualstudio.com.
  • Установите его, следуя стандартным инструкциям.
  • Откройте VS Code, перейдите в раздел расширений (квадратик слева) и установите расширение «Python» от Microsoft.
  • Ваша первая программа

    Традиционно изучение любого языка начинается с программы «Hello, World!». Давайте не будем нарушать традиции.

    Откройте VS Code, создайте новый файл и назовите его hello.py. Расширение .py сообщает компьютеру, что внутри находится код на Python. Впишите туда следующую строку:

    Запустите программу (обычно это кнопка Play в углу редактора). В нижней части экрана (в терминале) вы увидите надпись: Hello, World!.

    Разбор полетов: * print() — это функция. Команда компьютеру: «Напечатай то, что внутри скобок». * "Hello, World!" — это строка (текст). В Python текст всегда заключается в кавычки (одинарные или двойные).

    Переменные: коробки для данных

    Программы были бы бесполезны, если бы не умели запоминать информацию. Для этого используются переменные.

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

    !Метафора переменной: коробка с именем (названием переменной) и содержимым (значением).

    Пример создания переменной:

    Здесь мы создали две «коробки»:

  • В коробку с именем user_name положили строку "Alex".
  • В коробку с именем age положили число 25.
  • Знак = в программировании означает не равенство, а присваивание. Мы говорим: «Возьми значение справа и положи его в переменную слева».

    Правила именования переменных

    Чтобы Python вас понимал, нужно соблюдать правила: * Имя может состоять из букв, цифр и знака подчеркивания _. * Имя не может начинаться с цифры. * Нельзя использовать пробелы. * Python чувствителен к регистру: Age и age — это разные переменные.

    В Python принято использовать стиль snake_case (змеиный регистр): все буквы маленькие, слова разделяются подчеркиванием. Например: my_favorite_color, user_login_count.

    Типы данных

    В наши «коробки» можно класть разные вещи. Вот основные типы данных, с которыми вы будете работать 90% времени:

    | Тип данных | Название в Python | Пример | Описание | | :--- | :--- | :--- | :--- | | Целые числа | int (Integer) | 10, -5, 0 | Обычные числа без дробной части. | | Числа с плавающей точкой | float | 3.14, 2.5, -0.01 | Дробные числа. Разделитель — точка. | | Строки | str (String) | "Привет", 'Python' | Любой текст в кавычках. | | Логический тип | bool (Boolean) | True, False | Истина или Ложь. Используется для проверок. |

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

    Базовые алгоритмические конструкции

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

  • Следование (команды выполняются одна за другой).
  • Ветвление (выбор действия в зависимости от условия).
  • Цикл (повторение действий).
  • Следование мы уже видели: код читается сверху вниз. Давайте разберем ветвление.

    Условный оператор if (Ветвление)

    В жизни мы постоянно принимаем решения: «Если на улице дождь, то я возьму зонт, иначе я пойду в кепке». В Python это записывается с помощью конструкции if-else.

    Обратите внимание на синтаксис: * if (если) — начало проверки. * == — оператор сравнения (равно ли?). Не путайте с одиночным = (присваивание). * : (двоеточие) — обязательно ставится в конце строки с условием. * Отступы — это критически важная часть Python. Строки print(...) сдвинуты вправо (обычно на 4 пробела). Так Python понимает, какие команды относятся к блоку if, а какие — нет.

    Если условий больше двух, используется elif (сокращение от else if — иначе если):

    !Визуализация логики работы конструкции if-elif-else через классическую блок-схему.

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

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

    Важно помнить: input() всегда возвращает строку. Если вы попросите пользователя ввести возраст и захотите сравнить его с числом, вам нужно будет превратить строку в число с помощью int().

    Заключение

    Поздравляю! Вы сделали первый и самый важный шаг. Сегодня вы узнали: * Как установить Python и VS Code. * Как выводить текст на экран и запрашивать ввод. * Что такое переменные и какие типы данных бывают. * Как научить программу принимать решения с помощью if и else.

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

    Практикуйтесь, экспериментируйте с кодом и не бойтесь ошибок — это лучший способ учиться!

    2. Структуры данных и функции: работа со списками, словарями и создание модульного кода

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

    Добро пожаловать во вторую часть курса «Python: От новичка до профессионала». В предыдущей статье мы научились создавать переменные — наши «коробки» для хранения данных. Мы клали туда числа и строки, и это отлично работало для простых задач.

    Но представьте, что вам нужно написать программу для интернет-магазина. Вам нужно хранить список из 1000 товаров. Создавать 1000 переменных (item_1, item_2, ... item_1000) — это безумие. Или представьте, что вам нужно хранить информацию о пользователе: имя, возраст, адрес и email. Использовать для этого четыре разные переменные неудобно, ведь эти данные логически связаны.

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

    Списки (Lists): Порядок во всем

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

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

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

    Списки создаются с помощью квадратных скобок []. Элементы внутри разделяются запятыми.

    Индексация: Доступ к элементам

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

    Если вы попробуете обратиться к fruits[3], Python выдаст ошибку, так как элемента с индексом 3 не существует (у нас всего 3 элемента: 0, 1 и 2).

    Python также поддерживает отрицательную индексацию. Это удобно, когда нужно взять элемент с конца списка: * -1 — последний элемент. * -2 — предпоследний элемент.

    Методы списков

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

  • Добавление: метод .append() добавляет элемент в конец списка.
  • Удаление: метод .remove() удаляет элемент по значению.
  • Длина: функция len() сообщает количество элементов.
  • Цикл for: Обход списков

    В прошлой статье мы упоминали, что циклы нужны для повторения действий. Цикл for в Python идеально создан для работы со списками. Он берет элементы из списка по одному и выполняет с ними действия.

    Синтаксис читается как обычный английский: For item in list (Для каждого предмета в списке).

    Как это работает:

  • Переменная guest принимает значение "Мария". Выполняется код внутри блока.
  • Переменная guest принимает значение "Иван". Код выполняется снова.
  • Переменная guest принимает значение "Ольга". Код выполняется в последний раз.
  • Словари (Dictionaries): Ключ к успеху

    Списки хороши, когда важен порядок. Но что, если нам нужно хранить данные, у которых есть названия? Например, анкету пользователя. Запоминать, что под индексом 0 лежит имя, а под индексом 1 — телефон, очень неудобно.

    Здесь на помощь приходят словари (dict). Словарь — это набор пар «Ключ: Значение».

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

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

    Словари создаются с помощью фигурных скобок {}.

    Работа со словарем

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

    Отличия списка от словаря: * Список: Элементы упорядочены, доступ по индексу (0, 1, 2). Используется для наборов однотипных вещей (список покупок, список файлов). * Словарь: Порядок не гарантирован (в старых версиях Python), доступ по ключу. Используется для описания объектов со свойствами (товар, пользователь, машина).

    Функции: Искусство не повторяться

    Представьте, что вы пишете программу, которая поздравляет пользователя с днем рождения. Вам нужно вывести красивую рамку и текст. Если пользователей трое, вы можете скопировать код три раза. А если их 1000? Код станет огромным и неуправляемым.

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

    Создание функции

    Функция объявляется ключевым словом def (от англ. define — определить).

    Аргументы функции

    Функции становятся по-настоящему мощными, когда мы передаем им данные. Переменные, которые функция принимает на вход, называются аргументами.

    Возврат значения (return)

    Часто функция должна не просто что-то напечатать, а вычислить и вернуть результат, чтобы мы могли использовать его дальше. Для этого используется слово return.

    !Функция — это механизм: она берет сырые данные, обрабатывает их и возвращает готовый продукт.

    Если не использовать return, функция выполнит код, но результатом её работы будет пустота (None).

    Модули: Стоим на плечах гигантов

    Python славится своей философией «Батарейки в комплекте» (Batteries Included). Это значит, что вместе с языком устанавливается огромное количество готового кода для решения стандартных задач. Этот код упакован в модули.

    Вам не нужно писать сложную математику или функции для генерации случайных чисел с нуля. Достаточно подключить нужный модуль командой import.

    Пример: Модуль random

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

    Пример: Модуль math

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

    Практический пример: Объединяем всё вместе

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

    Заключение

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

    Что мы изучили: * Списки ([]) — для хранения упорядоченных наборов данных. * Словари ({}) — для хранения данных с именованными ключами. * Цикл for — для удобного перебора элементов списка. * Функции (def) — для упаковки логики в переиспользуемые блоки. * Модули (import) — для использования готовых инструментов Python.

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

    Продолжайте практиковаться, создавайте свои списки и пишите функции!

    3. Объектно-ориентированное программирование: классы, наследование, полиморфизм и инкапсуляция

    Объектно-ориентированное программирование: классы, наследование, полиморфизм и инкапсуляция

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

    Представьте, что вы разрабатываете компьютерную игру. У вас есть сотни персонажей, монстров и предметов. Если описывать каждого отдельными переменными и функциями, ваш код превратится в хаос. Здесь на сцену выходит Объектно-ориентированное программирование (ООП).

    ООП — это методология, которая позволяет программистам моделировать реальный мир. Вместо того чтобы писать просто набор команд, мы создаем «объекты», которые объединяют в себе данные (характеристики) и поведение (действия).

    Сегодня мы разберем четыре кита, на которых держится ООП: Классы, Инкапсуляция, Наследование и Полиморфизм.

    Классы и Объекты: Чертеж и Дом

    Самая важная концепция в ООП — это различие между классом и объектом.

    Класс — это чертеж, шаблон или инструкция. Он описывает, каким должен быть* объект. * Объект (или экземпляр класса) — это конкретная реализация этого чертежа.

    !Слева — класс (чертеж), справа — объекты (реальные дома).

    Давайте создадим класс для персонажа игры.

    Разберем этот код:

  • class Character: — мы объявляем новый класс.
  • __init__ — это специальный метод (конструктор). Он запускается автоматически, когда мы создаем новый объект. Здесь мы задаем начальные характеристики.
  • self — это ссылка на конкретный объект, с которым мы работаем прямо сейчас. Когда мы создаем десять разных персонажей, self позволяет программе понять, имя какого именно персонажа мы хотим узнать.
  • Теперь создадим объекты (экземпляры) этого класса:

    У нас есть один чертеж (Character), но два разных дома (hero и villain) с разными жильцами внутри.

    Инкапсуляция: Защита данных

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

    Это и есть инкапсуляция — сокрытие внутренней реализации и защита данных от прямого вмешательства.

    В Python нет строгой защиты (как private в Java или C++), но есть соглашение: если имя переменной начинается с нижнего подчеркивания _, трогать её снаружи не стоит.

    Используя методы (как deposit), мы можем контролировать, как меняются данные (например, запретить отрицательное пополнение).

    Наследование: Не повторяй себя

    Допустим, в нашей игре есть не просто персонажи, а Маги и Воины. У них есть общее (имя, здоровье), но есть и различия (у мага — мана, у воина — ярость).

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

    !Наследование позволяет дочерним классам перенимать свойства родительских.

    Теперь проверим:

    Класс Mage автоматически получил всё, что было в Character, и добавил свое. Это позволяет писать меньше кода и избегать ошибок.

    Полиморфизм: Один интерфейс, разное поведение

    Слово «полиморфизм» звучит страшно, но суть проста: разные объекты могут реагировать на одну и ту же команду по-разному.

    Представьте, что у вас есть кнопка «Атака». Если вы играете за Мага, эта кнопка запускает заклинание. Если за Воина — удар топором.

    Результат: * Гэндальф использует магию! * Арагорн бьет щитом!

    Программе не важно, кто именно находится в переменной hero. Главное, что у этого объекта есть метод attack(). Это дает огромную гибкость при расширении программы.

    Итоги

    Сегодня мы заложили фундамент профессиональной разработки на Python.

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

    Практикуйтесь в создании своих классов! Попробуйте описать свой любимый автомобиль или домашнее животное с помощью кода.

    4. Работа с файловой системой, обработка исключений и обзор стандартной библиотеки

    Работа с файловой системой, обработка исключений и обзор стандартной библиотеки

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

    Как только вы закрываете программу или выключаете компьютер, все данные исчезают. Переменные, списки, созданные вами объекты — всё это живет в оперативной памяти (RAM), которая очищается при завершении работы. Чтобы данные жили вечно (или хотя бы до тех пор, пока вы их не удалите), нам нужно научиться сохранять их на жесткий диск.

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

    Файловая система: Долговременная память

    Работа с файлами — это базовый навык любого программиста. Это позволяет сохранять прогресс в игре, записывать логи работы сервера или обрабатывать большие объемы данных.

    !Визуализация процесса сохранения данных из оперативной памяти на жесткий диск.

    Открытие и закрытие файлов

    В Python для работы с файлами используется встроенная функция open(). Она принимает два основных аргумента: имя файла и режим работы.

    Основные режимы работы: * 'r' (read) — чтение. Режим по умолчанию. Если файла нет, возникнет ошибка. * 'w' (write) — запись. Если файл существует, он будет полностью перезаписан. Если нет — создан новый. * 'a' (append) — дозапись. Данные добавляются в конец файла, старое содержимое сохраняется.

    Давайте попробуем записать что-нибудь в файл.

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

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

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

    Чтение из файла

    Теперь прочитаем то, что мы записали. Используем режим 'r'.

    Метод .read() считывает весь файл целиком в одну строку. Если файл огромный (например, несколько гигабайт), это может «повесить» компьютер. В таких случаях лучше читать файл построчно:

    Метод .strip() здесь нужен, чтобы убрать лишние символы переноса строки, так как print добавляет свой перенос, а в файле есть свой.

    Обработка исключений: Подушка безопасности

    Идеального кода не существует. Пользователь может ввести текст вместо числа, файл может быть удален, а интернет — отключиться. В обычном случае Python останавливает программу и выдает ошибку (Exception).

    Чтобы программа не «падала», мы используем конструкцию try-except (попытайся — исключи).

    !Страховочная сетка try-except, спасающая программу от падения.

    Базовая конструкция

    Как это работает:

  • Python пытается выполнить код внутри блока try.
  • Если все хорошо, блок except пропускается.
  • Если возникает ошибка, Python ищет соответствующий блок except.
  • Если находит — выполняет код внутри него, и программа продолжает работать дальше, не падая.
  • Блок finally

    Иногда нужно выполнить действие независимо от того, была ошибка или нет. Например, закрыть соединение с базой данных. Для этого существует блок finally.

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

    Мы уже касались модулей random и math. Но стандартная библиотека Python огромна. Знание того, что в ней есть, отличает новичка от профи. Зачем писать велосипед, если он уже есть в гараже?

    Работа с путями: модуль os и pathlib

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

    Однако в современном Python чаще используют модуль pathlib, так как он более удобен и работает в стиле ООП.

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

    Представьте, что у вас есть сложный словарь с настройками игры. Записывать его в файл как строку ("{'level': 5, 'score': 100}") неудобно, потому что потом сложно превратить эту строку обратно в словарь.

    Для этого используется формат JSON (JavaScript Object Notation). Это стандарт для хранения и передачи данных в вебе.

    Функция json.dump() превращает объекты Python в текст формата JSON и записывает в файл. Функция json.load() делает обратное.

    Работа со временем: модуль datetime

    Программистам часто нужно знать текущее время или вычислять разницу между датами.

    Заключение

    Сегодня вы сделали свои программы по-настоящему автономными и надежными.

    Что мы изучили:

  • Файловый ввод/вывод: Как сохранять данные на диск с помощью open() и with.
  • Обработка исключений: Как использовать try-except, чтобы ловить ошибки и не давать программе падать.
  • Стандартная библиотека: Познакомились с инструментами для работы с путями (os, pathlib), данными (json) и временем (datetime).
  • Теперь вы готовы к созданию полноценных приложений, которые сохраняют свое состояние и не боятся ошибок пользователя. В следующих уроках мы начнем выходить за пределы стандартной библиотеки и узнаем, как устанавливать сторонние пакеты, которые позволят нам делать практически всё: от создания веб-сайтов до анализа данных.

    Практикуйтесь! Попробуйте написать программу «Дневник», которая спрашивает у пользователя, как прошел день, и сохраняет ответ в файл с текущей датой.

    5. Продвинутые техники: декораторы, итераторы, генераторы и введение в асинхронность

    Продвинутые техники: декораторы, итераторы, генераторы и введение в асинхронность

    Добро пожаловать в пятую часть курса «Python: От новичка до профессионала». Мы уже прошли долгий путь: от написания первой строчки print("Hello World") до создания сложных классов и работы с файловой системой. Ваши программы становятся всё более функциональными и надежными.

    Однако, по мере роста мастерства, программист начинает задумываться не только о том, что делает код, но и о том, как он это делает. Насколько код красив? Эффективно ли он использует память? Может ли он делать несколько дел одновременно?

    Сегодня мы заглянем «под капот» Python и изучим инструменты, которые делают этот язык по-настоящему мощным и выразительным. Мы разберем декораторы (магию изменения функций), итераторы и генераторы (секреты эффективной работы с данными) и коснемся асинхронности — способности программы не ждать, пока закипит чайник.

    Декораторы: Обертка для функций

    В Python функции являются «гражданами первого класса». Это означает, что функцию можно положить в переменную, передать как аргумент другой функции или даже вернуть из функции. Именно на этом свойстве строятся декораторы.

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

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

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

    Зачем это нужно?

    Допустим, у вас есть 10 разных функций, и вы хотите замерять время выполнения каждой из них. Писать код таймера внутри каждой функции — это нарушение принципа DRY (Don't Repeat Yourself — не повторяйся). Декоратор позволяет написать код таймера один раз и применить его ко всем функциям.

    Синтаксис декоратора

    В Python для применения декоратора используется символ @ (синтаксический сахар).

    Давайте напишем декоратор, который просто сообщает о начале и конце работы функции.

    Результат вывода:

    Когда Python видит @my_decorator над функцией say_hello, он фактически делает следующее: say_hello = my_decorator(say_hello). Теперь переменная say_hello хранит не оригинальную функцию, а функцию wrapper, внутри которой спрятан оригинал.

    Итераторы: Как на самом деле работает цикл for

    Мы постоянно используем цикл for для перебора списков, строк и словарей. Но задумывались ли вы, как Python понимает, какой элемент следующий?

    Все дело в протоколе итерации. В Python есть два понятия:

  • Итерируемый объект (Iterable): Это всё, что можно перебрать (список, строка, кортеж). У таких объектов есть метод __iter__().
  • Итератор (Iterator): Это специальный объект, который выдает элементы по одному. У него есть метод __next__().
  • Когда вы пишете for i in my_list, происходит следующее:

  • Python неявно вызывает iter(my_list), получая итератор.
  • Затем он бесконечно вызывает функцию next() у этого итератора.
  • Когда элементы заканчиваются, итератор вызывает специальное исключение StopIteration, и цикл останавливается.
  • Вы можете проверить это вручную:

    Генераторы: Ленивые вычисления

    Списки — это удобно, но они хранят все данные в оперативной памяти сразу. Представьте, что вам нужно обработать последовательность из миллиарда чисел. Если вы создадите список numbers = [1, 2, 3, ... 1000000000], ваш компьютер, скорее всего, зависнет, так как ему не хватит памяти (RAM).

    Здесь на помощь приходят генераторы.

    Генератор — это функция, которая не возвращает результат целиком (через return), а порождает (yield) значения по одному по мере необходимости. Она «запоминает», где остановилась, и при следующем вызове продолжает с того же места.

    !Список загружает все данные в память сразу, как грузовик. Генератор создает данные по одному по запросу, экономя место.

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

    Чтобы превратить обычную функцию в генератор, достаточно заменить return на yield.

    Как это работает:

  • Цикл запрашивает число.
  • Функция запускается, доходит до yield count (где count=0), отдает 0 и «замерзает».
  • Цикл печатает 0 и просит следующее.
  • Функция «размораживается» сразу после yield, увеличивает count и снова доходит до yield (теперь 1).
  • Генераторные выражения

    Помните списковые включения (list comprehensions)? Генераторы можно создавать так же просто, заменив квадратные скобки [] на круглые ().

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

    Введение в асинхронность: Делаем несколько дел сразу

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

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

    Синхронный vs Асинхронный подход

    * Синхронно (Блокирующий код): 1. Поставить чайник (ждем 5 мин). 2. Нарезать хлеб. Итог: 5 мин + время на нарезку.

    * Асинхронно (Неблокирующий код): 1. Поставить чайник (не ждем, а переключаем внимание). 2. Пока чайник греется, нарезать хлеб. 3. Вернуться к чайнику, когда он закипит. Итог: Максимум из двух времен (скорее всего, 5 мин).

    Библиотека asyncio

    В Python для асинхронности используется библиотека asyncio и ключевые слова async и await.

    * async def — объявляет функцию асинхронной (корутиной). * await — говорит программе: «Здесь нужно подождать результат, но пока ждешь, можешь заняться другими полезными делами».

    Пример (упрощенный):

    Результат:

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

    Заключение

    Сегодня вы перешли черту, отделяющую новичка от продвинутого пользователя Python. Вы узнали:

  • Декораторы позволяют изменять поведение функций, не переписывая их код.
  • Итераторы — это механизм, который заставляет работать циклы for.
  • Генераторы и yield позволяют обрабатывать огромные объемы данных, экономя память.
  • Асинхронность (async/await) позволяет программе выполнять задачи параллельно, не блокируя основной поток выполнения.
  • Эти инструменты сделают ваш код не только быстрее, но и профессиональнее. В следующих статьях мы применим эти знания на практике, когда начнем изучать работу с сетью и создание веб-приложений.

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