Перейти к содержимому
Поиск
Разработка

Python: полный мануал с примерами и справочником функций

Полный практический мануал Python: от установки и синтаксиса до файлов, сети, тестов и проектов. 25 глав, справочник функций и методов, упражнения с решениями и 195 проверенных примеров.

Александр Некрасов
Python: практический мануал с кодом, папкой и схемой работы

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

Выберите одну из 25 глав или найдите нужную функцию через поиск. В справочнике собраны все 73 позиции официальной таблицы встроенных функций и типов Python 3.15, а также 161 метод и 12 свойств строк, коллекций и путей. Для каждой позиции есть назначение, важный нюанс и ссылка на первичную документацию.

Код можно копировать и скачивать. 195 самостоятельных примеров проверены запуском на Python 3.15.0; у упражнений есть решения и ожидаемый результат. Новые возможности языка отмечены в тексте, а интерактивные фрагменты и команды установки объяснены отдельно.

Если начинаете с нуля, открывайте главы по порядку. Если решаете конкретную задачу, ищите по-русски или по имени Python: open, str.split, Path.read_text.

Python 3.15.025 главПримеры проверены запуском
Все главы руководства 25

Глава 24 · практика

Законченные проекты и перенос на свой компьютер

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

Законченный проект начинается с проверяемого результата

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

Выберите одну полезную задачу и доведите её до конца. Например, объедините одинаковые позиции таблицы, выведите проверенные итоги и сохраните отчёт. Не начинайте одновременно строить веб-интерфейс, авторизацию, фоновые задачи и универсальный импорт любого формата. Граница проекта может быть небольшой и честной: UTF-8 CSV с известными колонками, целое неотрицательное количество, один локальный запуск. Когда такие ограничения записаны, проверить программу легче, а пользователь понимает, какие данные ему нужно подготовить. Расширение формата станет отдельным изменением с собственными примерами.

Проект 1: CSV → JSON → SQLite

Следующий проект читает полностью предоставленный учебный sales.csv, объединяет количество по названию и сохраняет JSON в собственной временной папке. SQLite используется в памяти: реальные базы не открываются. Отдельная проверка сравнивает JSON и результат SQL-выборки. В таком отчёте количество — целое число; для денежных сумм потребовалось бы другое явно выбранное представление. При первом неправильном значении импорт прекращается до сохранения результата, поэтому частичный отчёт не будет выглядеть завершённым.

import csv
import json
import sqlite3
from pathlib import Path
from tempfile import TemporaryDirectory

def load_totals(path):
    totals = {}
    with path.open(encoding="utf-8", newline="") as stream:
        reader = csv.DictReader(stream)
        if reader.fieldnames != ["name", "quantity"]:
            raise ValueError("Нужны колонки name,quantity")
        for number, row in enumerate(reader, start=2):
            if set(row) != {"name", "quantity"} or row["name"] is None or row["quantity"] is None:
                raise ValueError(f"Неверное число полей в строке {number}")
            name = row["name"].strip()
            try:
                quantity = int(row["quantity"])
            except ValueError as error:
                raise ValueError(f"Количество в строке {number} должно быть целым") from error
            if not name or quantity < 0:
                raise ValueError(f"Некорректная строка {number}")
            totals[name] = totals.get(name, 0) + quantity
    return [{"name": name, "quantity": totals[name]} for name in sorted(totals)]

records = load_totals(Path("sales.csv"))
with TemporaryDirectory() as folder:
    path = Path(folder) / "report.json"
    path.write_text(json.dumps(records, ensure_ascii=False), encoding="utf-8")
    connection = sqlite3.connect(":memory:", autocommit=False)
    try:
        with connection:
            connection.execute("CREATE TABLE totals (name TEXT PRIMARY KEY, quantity INTEGER NOT NULL)")
            connection.executemany("INSERT INTO totals VALUES (?, ?)", [(row["name"], row["quantity"]) for row in records])
        fetched = [{"name": name, "quantity": quantity} for name, quantity in connection.execute("SELECT name,quantity FROM totals ORDER BY name")]
        print("Позиций:", len(fetched))
        print("Всего единиц:", sum(row["quantity"] for row in fetched))
        print("JSON и SQLite согласованы:", json.loads(path.read_text(encoding="utf-8")) == fetched)
        for row in fetched:
            print(row["name"], row["quantity"])
    finally:
        connection.close()
Позиций: 2
Всего единиц: 9
JSON и SQLite согласованы: True
Кабель 5
Клемма 4

Проверьте четыре сценария: обычную таблицу, только строку заголовков, отрицательное количество и неверные колонки. Для пустой таблицы итоговые количества равны нулю, а список позиций пуст. Если задача требует собирать все ошибки строк, добавьте отдельный список диагностики и условие публикации результата; не проглатывайте ошибки без отметки. Преобразование названий также должно быть осознанным: strip удаляет крайние пробелы, но не объединяет разные регистры и варианты написания. Решение о такой нормализации относится к предметной задаче, а не к JSON или SQL.

Для постоянной CLI-базы вместо :memory: понадобится явно выбранный путь. Продумайте повторный запуск: повторная вставка уже импортированного файла не должна удвоить итог случайно. Можно хранить идентификатор партии и уникальное ограничение либо полностью заменять одну известную учебную выборку в транзакции. После успешного импорта команда inspect покажет число строк и итог, а export сохранит JSON. Разделение этих команд позволяет человеку сначала осмотреть состояние и только затем запустить действие. Наличие SQLite само по себе не определяет такую политику.

Проект 2: список файлов с проверяемыми характеристиками

Второй проект составляет отчёт о собственной учебной папке. Он сохраняет относительное имя, размер в байтах и SHA-256 каждого TXT-файла. Это позволяет сравнить исходники при переносе и заметить изменение содержимого. Хеш не доказывает авторство и безопасность файла; он подтверждает совпадение байтов при выбранном алгоритме. Отчёт записывается вне входной папки, чтобы следующий запуск не включил его в собственный вход. Для большого набора данных чтение хеша лучше выполнять по блокам, не загружая каждый файл целиком в память.

import hashlib
import json
from pathlib import Path
from tempfile import TemporaryDirectory

def digest(path):
    value = hashlib.sha256()
    with path.open("rb") as stream:
        for block in iter(lambda: stream.read(8192), b""):
            value.update(block)
    return value.hexdigest()

with TemporaryDirectory() as folder:
    root = Path(folder)
    source = root / "input"
    source.mkdir()
    (source / "a.txt").write_text("abc", encoding="utf-8")
    (source / "b.txt").write_text("Привет", encoding="utf-8")
    (source / "notes.md").write_text("не входит", encoding="utf-8")
    records = []
    for path in sorted(source.glob("*.txt")):
        if path.is_file() and not path.is_symlink():
            records.append({"path": path.relative_to(source).as_posix(), "bytes": path.stat().st_size, "sha256": digest(path)})
    report = root / "manifest.json"
    report.write_text(json.dumps(records, ensure_ascii=False, indent=2), encoding="utf-8")
    print("Файлов:", len(records))
    print("Байтов:", sum(record["bytes"] for record in records))
    print("Длина всех хешей 64:", all(len(record["sha256"]) == 64 for record in records))
    print("Имена:", ", ".join(record["path"] for record in records))
Файлов: 2
Байтов: 15
Длина всех хешей 64: True
Имена: a.txt, b.txt

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

Проект 3: исходники, README и тест в одном архиве

Передайте человеку не только запускаемый файл, но и краткую инструкцию, учебные данные и способ проверки. В примере архив содержит модуль расчёта, точку входа пакета, минимальные метаданные, README, данные и тест. Скрипт создаёт ZIP во временной папке и проверяет CRC без распаковки. Файлы перечислены явно: случайные документы рабочей папки в архив не попадут. Это архив исходного проекта, а не автоматически собранный wheel. Установка дистрибутива и упаковка исходников — разные результаты, которые нужно называть точно.

import io
import unittest
from pathlib import Path
from tempfile import TemporaryDirectory
from zipfile import ZipFile, ZIP_DEFLATED
from manual_project.core import total

paths = ["manual_project/__init__.py", "manual_project/core.py", "manual_project/__main__.py", "tests/test_core.py", "README.md", "pyproject.toml", "data/example.csv"]
suite = unittest.defaultTestLoader.discover("tests")
result = unittest.TextTestRunner(stream=io.StringIO()).run(suite)
if not result.wasSuccessful():
    raise RuntimeError("Тесты не прошли")
with TemporaryDirectory() as folder:
    archive_path = Path(folder) / "manual-project.zip"
    with ZipFile(archive_path, "w", compression=ZIP_DEFLATED) as archive:
        for relative in paths:
            archive.write(Path(relative), arcname=relative)
    with ZipFile(archive_path) as archive:
        print("Записей:", len(archive.namelist()))
        print("CRC корректен:", archive.testzip() is None)
print("Тестов:", result.testsRun)
print("Итого:", total([2, 3]))
Записей: 7
CRC корректен: True
Тестов: 4
Итого: 5

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

Воспроизведите запуск в новом окружении

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

python -m venv .venv
# Windows, без активации:
.venv\Scripts\python.exe -m manual_project
.venv\Scripts\python.exe -m unittest discover -s tests
# macOS/Linux, без активации:
.venv/bin/python -m manual_project
.venv/bin/python -m unittest discover -s tests

Для настоящего устанавливаемого пакета pyproject.toml должен соответствовать выбранному сборщику и структуре файлов. Получение wheel обычно требует инструмента сборки и его зависимостей; setuptools в нашем описании — сторонний сборщик, не часть стандартной библиотеки. Не утверждайте, что архив уже прошёл сборку, если вы лишь добавили такой файл. Сначала проверьте построенный дистрибутив и установку в чистую среду. Если пакет предоставляет CLI, добавьте осмысленную точку входа project.scripts и проверку --help без побочных действий.

Добавляйте HTTP и async, когда задача это требует

Локальный HTTP-стенд из главы о сети можно связать с отчётом: обработчик возвращает заранее проверенный JSON, клиент проверяет статус и схему, а расчёт остаётся той же отдельной функцией. Это удобный учебный обмен между двумя слоями, но ещё не публичный сервис. Не объявляйте его готовой производственной системой без требований к доступу, хранению, нагрузке и сопровождению. Начните с localhost и синтетических данных. В тестах чистого расчёта заменяйте источник: реальный запуск сервера нужен только проверке сетевого взаимодействия.

Асинхронный вариант полезен, когда независимые операции действительно ждут I/O и библиотеки поддерживают async. Он не ускоряет sum и не делает обычное чтение файла неблокирующим. Сохраните прежний формат результата, ограничьте число одновременно выполняемых операций и договоритесь, что делать с одной неудачей. TaskGroup помогает связать время жизни задач; их результаты затем оформляются последовательно. Перед обновлением модели сравните результаты с последовательной версией на одинаковых входных данных, а производительность измерьте отдельно от корректности.

Диагностика запуска и обновление Python

При переносе сначала проверьте sys.executable, версию Python и рабочую папку; затем входные файлы и установленные зависимости. Ошибка ModuleNotFoundError может означать другую среду, неверный способ запуска пакета или действительно отсутствующий пакет. Сообщение об относительном импорте часто связано с запуском файла напрямую вместо python -m. Проверьте также свои имена: файл json.py способен заслонить стандартную библиотеку. Эта короткая последовательность полезнее переустановки всей системы без причины. Диагностика должна помогать исправлению, а не требовать раскрытия полного окружения с секретами.

Версия этого руководства проверена на Python 3.15.0 по состоянию на 12 октября 2026 года. Минимальная версия отдельного примера указана в его метаданных; новый lazy import не запускается на 3.14. При обновлении сначала создайте новую среду, установите зависимости и выполните известные тесты и примеры, затем проверьте предупреждения и изменения поведения. Сохраните рабочую прежнюю среду до подтверждения результата. Совпадение номера Python не гарантирует одинаковые возможности сборки, расширений или данных часовых поясов; такие требования указываются отдельно.

Практика: несколько источников и один итог

Объедините три асинхронных учебных источника в один упорядоченный отчёт. Каждый источник должен вернуть данные, а не печатать их. После выхода из TaskGroup получите результаты, вычислите общий итог и только затем оформите вывод. Проверьте вариант с пустым источником: пустая выборка может быть допустимой, если контракт считает её нулём. Для настоящего сервиса добавьте ограничение параллельности, таймаут и проверку схемы; в упражнении внешняя сеть не используется.

Посмотреть решение
import asyncio

async def load(values):
    await asyncio.sleep(0)
    if any(type(value) is not int or value < 0 for value in values):
        raise ValueError("Неверные значения")
    return sum(values)

async def main():
    async with asyncio.TaskGroup() as group:
        tasks = [group.create_task(load(values)) for values in [[2, 3], [], [4]]]
    subtotals = [task.result() for task in tasks]
    print("Источники:", subtotals)
    print("Итого:", sum(subtotals))

asyncio.run(main())
Источники: [5, 0, 4]
Итого: 9

Примеры и материалы с собой

Архив содержит наши самостоятельные примеры, тестовые данные, ожидаемый результат и README. Указанные команды установки и фрагменты REPL отделены от скриптов, которые проверены запуском.

Сверено с официальной документацией 2026-10-12. Стандартная библиотека и сторонние пакеты различаются; ссылки на источники есть в каждой главе.