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

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

Глава 20 · средний

Командная строка и автоматизация

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

Параметры лучше редактирования исходника

CLI — программа, которой передают параметры из терминала или другой программы. Хороший инструмент сообщает, что принимает, куда сохраняет результат и как проверить действие до его выполнения. В примере argparse превращает строки аргументов в проверенные значения. Для воспроизводимого запуска передаётся конкретный список; в настоящей точке входа parse_args() без списка читает аргументы процесса. Поэтому справка, типы и значения по умолчанию должны описывать пользовательское действие, а не внутренние переменные реализации.

import argparse

def positive(text):
    value = int(text)
    if value <= 0:
        raise argparse.ArgumentTypeError("нужно число больше нуля")
    return value

parser = argparse.ArgumentParser(prog="report", description="Отчёт по учебной таблице")
parser.add_argument("input", help="входной CSV-файл")
parser.add_argument("--limit", type=positive, default=10, help="максимум строк")
parser.add_argument("--dry-run", action="store_true", help="показать план без записи")
args = parser.parse_args(["sales.csv", "--limit", "2", "--dry-run"])
print("Вход:", args.input)
print("Лимит:", args.limit)
print("Без записи:", args.dry_run)
Вход: sales.csv
Лимит: 2
Без записи: True

Строки sys.argv ещё не являются проверенными числами или путями. Позиционные аргументы подходят для обязательных входов, именованные опции — для настроек. Значение по умолчанию должно быть безопасным и понятным. Когда у инструмента несколько разных действий, подкоманды вроде inspect и convert читаются лучше многочисленных взаимоисключающих флагов. Проверяйте аргументы до тяжёлой работы и изменения файлов; отдельное сообщение об ошибочном лимите полезнее исключения из середины обработки.

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

Результат в stdout, диагностика в stderr

Стандартный вывод stdout позволяет передать результат следующей программе или сохранить его в файл. Стандартный поток ошибок stderr предназначен для диагностики. Если CLI обещает JSON, строка «начинаю обработку» в stdout ломает этот контракт. Завершение с кодом 0 означает успех; ненулевой код сообщает о неуспехе, а конкретные значения документирует инструмент. Не возвращайте 0 после ошибки записи только потому, что исключение перехвачено: планировщик тогда сочтёт задачу выполненной.

Практичная структура — функция main(argv=None), возвращающая код, и raise SystemExit(main()) под защитой __main__. Внутренние функции возвращают данные или вызывают осмысленные исключения; только внешний слой переводит их в сообщение и код завершения. Так расчёт можно тестировать без завершения всего тестового процесса. Справка --help обычно заканчивает запуск успешно; ошибка разбора аргументов у argparse обычно использует код 2. В демонстрации ниже считываются только заранее подготовленные учебные данные.

import argparse
import csv
import json
from pathlib import Path

def main(argv=None):
    parser = argparse.ArgumentParser(prog="csv-json")
    parser.add_argument("input", nargs="?", default="sales.csv")
    args = parser.parse_args(argv)
    with Path(args.input).open(encoding="utf-8", newline="") as stream:
        reader = csv.DictReader(stream)
        if reader.fieldnames != ["name", "quantity"]:
            raise ValueError("Ожидаются колонки name,quantity")
        rows = []
        for row in reader:
            if set(row) != {"name", "quantity"} or row["name"] is None or row["quantity"] is None:
                raise ValueError("Неверное число полей")
            value = int(row["quantity"])
            if not row["name"].strip() or value < 0:
                raise ValueError("Некорректная строка")
            rows.append({"name": row["name"].strip(), "quantity": value})
    print(json.dumps(rows, ensure_ascii=False, sort_keys=True))
    return 0

if __name__ == "__main__":
    import sys
    try:
        status = main()
    except (OSError, ValueError) as error:
        print("Ошибка:", error, file=sys.stderr)
        status = 2
    raise SystemExit(status)
[{"name": "Кабель", "quantity": 3}]

Объясните рабочую папку и выходной файл

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

Предварительный план должен совпадать с выполнением

Режим --dry-run рассчитывает тот же план, который использует настоящее выполнение, но не применяет изменения. Это помогает проверить имя выходного файла, число записей и порядок. Не делайте отдельный приблизительный алгоритм «для красивого превью»: он быстро начнёт отличаться от реального действия. В примере план строится один раз, сортируется, затем передаётся в ограниченное выполнение. Учебная папка создаётся внутри временного каталога и удаляется после опыта; файлы пользователя не затрагиваются.

from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as folder:
    root = Path(folder)
    for name in ["b.txt", "a.txt"]:
        (root / name).write_text("demo", encoding="utf-8")
    plan = [(path, path.with_suffix(".md")) for path in sorted(root.glob("*.txt"))]
    for source, target in plan:
        print("План:", source.name, "->", target.name)
    print("После dry-run:", len(list(root.glob("*.txt"))), "TXT")
    for source, target in plan:
        if target.exists():
            raise FileExistsError(target.name)
        source.rename(target)
    print("После выполнения:", len(list(root.glob("*.md"))), "MD")
План: a.txt -> a.md
План: b.txt -> b.md
После dry-run: 2 TXT
После выполнения: 2 MD

Передавайте дочернему процессу список аргументов

subprocess.run подходит для запуска локальной вспомогательной команды. Передавайте аргументы списком, сохраняйте shell=False, задавайте таймаут и решайте, нужен ли check=True. Для запуска того же Python используйте sys.executable: команда python из PATH может выбрать другую среду. Пробелы и кавычки внутри одного аргумента не требуют ручной сборки shell-строки. При check возникает CalledProcessError для ненулевого завершения; превышение таймаута вызывает TimeoutExpired. Не путайте эти случаи с отсутствием самого исполняемого файла.

import subprocess
import sys

process = subprocess.run(
    [sys.executable, "-c", "import sys; print(sys.argv[1])", "аргумент с пробелами"],
    shell=False, check=True, capture_output=True,
    text=True, encoding="utf-8", timeout=5,
)
print("Код:", process.returncode)
print(process.stdout, end="")
Код: 0
аргумент с пробелами

Shell-команды Windows и POSIX имеют разные правила экранирования. Модуль shlex ориентирован на Unix-подобные оболочки и не является универсальным Windows-парсером. Нужные операции с файлами проще выполнить через pathlib или shutil, чем запускать встроенную shell-команду. При необходимости дочернему процессу передают выбранный cwd и окружение; не выводите весь словарь окружения в лог. Комбинация capture_output и огромного вывода также требует решения о памяти: для потокового журнала используйте подходящую обработку потоков.

Настройки, платформа и завершение

Выберите приоритет настроек: например, явная опция, затем переменная окружения, затем значение по умолчанию. Переменная окружения — строка, которую нужно преобразовать и проверить. Имена собственного инструмента лучше делать специфичными, не меняя PATH или HOME ради лимита отчёта. platform помогает описать среду в диагностике, но без необходимости не ветвите простой алгоритм по названию системы. При Ctrl+C корректно освободите файлы и другие ресурсы; переносимость сигналов ограничена платформой, а сигнал завершения не гарантирует выполнение любого cleanup.

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

Сделайте проверку лимита 1–100 и используйте её как тип аргумента. Проверьте текст «10», ноль, нечисловую строку и 101. В примере функция вызывает ArgumentTypeError, чтобы argparse мог оформить пользовательскую ошибку. При упаковке настоящего инструмента добавьте команду в project.scripts файла pyproject.toml; это устанавливаемая точка входа, а не команда, которую нужно вручную копировать каждому пользователю в глобальную папку.

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

def limit(text):
    try:
        value = int(text)
    except ValueError as error:
        raise argparse.ArgumentTypeError("Лимит должен быть целым") from error
    if not 1 <= value <= 100:
        raise argparse.ArgumentTypeError("Лимит должен быть от 1 до 100")
    return value

for text in ["10", "0", "нет", "101"]:
    try:
        print(limit(text))
    except argparse.ArgumentTypeError as error:
        print(error)
10
Лимит должен быть от 1 до 100
Лимит должен быть целым
Лимит должен быть от 1 до 100

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

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

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