Перейти к основному содержимому

5.02. Архитектура Python

Разработчику Архитектору

Архитектура Python

Дистрибутив Python

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

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

После установки дистрибутива на диске формируется иерархическая структура каталогов. Корневой каталог содержит исполняемый файл интерпретатора python.exe (Windows) или python3 (Unix-системы), скрипты утилит в подкаталоге Scripts, модули стандартной библиотеки в подкаталоге Lib, скомпилированные расширения на C в подкаталоге DLLs (Windows) или lib-dynload (Unix), а также документацию и примеры кода. Эта структура обеспечивает предсказуемое расположение компонентов и упрощает автоматизацию процессов разработки и развертывания.

В комплекте также устанавивается IDLE.

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


CPython

Центральной реализацией Python является CPython — эталонная и наиболее распространённая реализация, написанная на C. Именно её вы скачиваете с официального сайта python.org , именно она используется в подавляющем большинстве проектов, от скриптов до масштабируемых сервисов.

Работа CPython включает следующие компоненты:

  • Lexer и Parser — разбор синтаксиса.
  • Compiler — компилятор, его задача - генерация байткода.
  • Interpreter Loop (PVM) — виртуальная машина для выполнения байткода.
  • Memory Manager — управление памятью через счётчик ссылок и сборщик мусора.
  • Global Interpreter Lock (GIL) — механизм, ограничивающий выполнение байткода одним потоком одновременно. Это ограничивает параллелизм в CPU-bound задачах, но не мешает эффективному использованию асинхронности и многопроцессорности.

Альтернативные реализации, такие как PyPy (с JIT-компиляцией), Jython (для JVM) и IronPython (.NET), предлагают другие компромиссы, но CPython остаётся стандартом де-факто.

CPython — это интерпретатор и полная система выполнения, включающая, как мы выяснили, парсер, компилятор в байт-код, виртуальную машину PVM, менеджер памяти, сборщик мусора и GIL. Давайте подробнее.

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

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

Виртуальная машина Python представляет собой исполнительную среду, предназначенную для выполнения байт-кода. Байт-код — это промежуточное представление программы, генерируемое компилятором Python из абстрактного синтаксического дерева. Виртуальная машина интерпретирует инструкции байт-кода последовательно, преобразуя их в вызовы низкоуровневых функций, реализованных на языке C. Каждая инструкция байт-кода соответствует простой операции: загрузка значения, вызов функции, арифметическое действие или управление потоком выполнения. Виртуальная машина управляет стеком вызовов, кадрами стека для каждой функции и таблицами локальных и глобальных переменных. Выполнение байт-кода происходит медленнее нативного кода процессора, но обеспечивает переносимость программ между различными аппаратными платформами и операционными системами. Файлы с расширением .pyc хранят скомпилированный байт-код для ускорения последующих запусков модулей.

Менеджер памяти Python отвечает за распределение и освобождение оперативной памяти во время выполнения программы. Этот компонент реализует многоуровневую систему управления памятью. На нижнем уровне менеджер взаимодействует с операционной системой через системные вызовы malloc и free для получения крупных блоков памяти. На среднем уровне реализованы пулы объектов — заранее выделенные области памяти для объектов одинакового размера. Пулы ускоряют выделение памяти для часто создаваемых объектов, таких как целые числа или короткие строки. На верхнем уровне менеджер предоставляет единый интерфейс для всех объектов Python, независимо от их типа. Каждый объект в Python содержит заголовок с метаданными: счетчик ссылок, указатель на тип объекта и дополнительные поля, специфичные для типа. Счетчик ссылок отслеживает количество активных ссылок на объект. При достижении нулевого значения счетчика память объекта немедленно возвращается в пул для повторного использования. Менеджер памяти работает совместно со сборщиком мусора для обработки циклических ссылок, которые счетчик ссылок не может обнаружить.


Процесс запуска Python скрипта

Процесс запуска Python-скрипта проходит через несколько этапов:

  1. Лексический анализ (Lexer). На первом шаге исходный код (*.py) разбивается на лексемы — минимальные значимые единицы: ключевые слова, операторы, идентификаторы, строки и т.д. Например, строка x = 5 + 3 превращается в последовательность: [ID(x), ASSIGN, INT(5), PLUS, INT(3)].

  2. Синтаксический анализ (Parser). Лексемы передаются парсеру, который строит абстрактное синтаксическое дерево (AST) — иерархическую структуру, отражающую логику программы. Это дерево становится основой для дальнейшей компиляции.

  3. Компиляция в байткод. Из AST генерируется байткод — платформо-независимый набор инструкций, предназначенный для выполнения на виртуальной машине Python (PVM). Байткод сохраняется в файлах .pyc в папке __pycache__.

import dis
def hello():
return "Hello"

dis.dis(hello)
# Выход:
# 2 0 LOAD_CONST 1 ('Hello')
# 2 RETURN_VALUE

  1. Интерпретация байткода (PVM). Байткод выполняется на Python Virtual Machine (PVM) — цикле, который читает и исполняет инструкции по одной. PVM — это часть CPython, написанная на C, и именно она обеспечивает кроссплатформенность. Хотя Python часто называют «интерпретируемым», он всё же компилируется в байткод, что делает его гибридной системой, близкой к Java или .NET.

  2. Управление памятью. Память в Python управляется автоматически:

    • Счётчик ссылок — основной механизм: каждый объект хранит количество ссылок на него. Когда оно достигает нуля, объект немедленно удаляется.
    • Сборщик мусора (GC) — дополняет систему, обнаруживая и удаляя циклические ссылки, которые счётчик не может обработать. Объекты живут в private heap — закрытой области памяти, управляемой интерпретатором. Разработчик не имеет прямого доступа к указателям.
  3. Global Interpreter Lock (GIL). GIL — это мьютекс (взаимное исключение), который гарантирует, что только один поток одновременно выполняет байткод. Это означает, что даже на многопроцессорных системах CPU-bound задачи не могут быть параллельны в рамках одного процесса. Что это значит на практике?

    • Для I/O-bound задач (сетевые запросы, файлы, базы данных) асинхронность (async/await) и многопоточность остаются эффективными.
    • Для CPU-bound задач (расчёты, обработка массивов) необходимо использовать многопроцессорность (multiprocessing) или переходить на PyPy.

GIL является компромиссом ради простоты и производительности в типичных сценариях. Его удаление — предмет активных дискуссий (PEP 703).


Модульность

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

Модуль — это файл с расширением .py, содержащий код: функции, классы, переменные, выражения.

# math_utils.py
def add(a, b):
return a + b

PI = 3.14159

Импорт:

import math_utils
print(math_utils.add(2, 3)) # 5

from math_utils import PI
print(PI) # 3.14159

Каждый модуль — это пространство имён (namespace). Имена модулей должны быть в стиле snake_case. При импорте модуль выполняется один раз и кэшируется в sys.modules.


Пакеты

Код можно организовать в иерархию через пакеты.

Пакет — это каталог, содержащий файл __init__.py (может быть пустым), который сообщает интерпретатору, что каталог является пакетом.

Структура:

my_package/
__init__.py
module_a.py
subpackage/
__init__.py
module_b.py

Импорт:

import my_package.module_a
from my_package.subpackage import module_b

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


Стандартная библиотека

Python поставляется с мощной стандартной библиотекой, часто называемой «batteries included». Она включает сотни модулей, предоставляющих готовые решения для типичных задач программирования. Библиотека разделена на категории: модули для работы с операционной системой (os, sys, pathlib), обработки текста (re, json, csv), сетевого взаимодействия (socket, http, smtplib), манипуляции данными (datetime, collections, itertools), криптографии (hashlib, ssl) и многие другие. Модули стандартной библиотеки написаны на языке Python и на C для критичных к производительности компонентов. Все модули доступны сразу после установки интерпретатора без необходимости дополнительной загрузки или компиляции. Стандартная библиотека проходит тот же цикл тестирования и версионирования, что и сам интерпретатор, обеспечивая стабильность и совместимость между версиями.

Вот ключевые модули:

МодульНазначение
osРабота с операционной системой: файлы, пути, переменные окружения.
sysДоступ к параметрам интерпретатора:argv,path,exit().
jsonСериализация/десериализация JSON.
csvЧтение и запись CSV-файлов.
datetimeРабота с датами и временем.
randomГенерация случайных чисел.
mathМатематические функции:sin,log,sqrt.
stringКонстанты и методы для работы со строками.
emailСоздание и разбор email-сообщений.
httpРабота с HTTP: клиент (client), сервер (server).
sslПоддержка SSL/TLS для безопасного соединения.
tkinterСоздание графических интерфейсов (GUI).

Эти модули не требуют установки и доступны в любом окружении Python.


Менеджеры пакетов и репозитории

Для управления внешними библиотеками используются менеджеры пакетов и репозитории. Их вкратце мы уже упоминали.

Менеджер пакетов pip обеспечивает установку, обновление и удаление сторонних библиотек из репозитория PyPI. Утилита получает доступ к центральному хранилищу пакетов, разрешает зависимости между библиотеками и автоматически устанавливает требуемые компоненты. Команды pip install, pip uninstall и pip list предоставляют базовый интерфейс для управления установленными пакетами. Менеджер поддерживает виртуальные окружения через интеграцию с модулем venv, позволяя изолировать зависимости разных проектов. Файлы requirements.txt фиксируют точные версии пакетов для воспроизводимости окружения разработки. Менеджер pip входит в состав дистрибутива Python начиная с версии 3.4 и обновляется независимо от основного интерпретатора через команду pip install --upgrade pip.

PyPI — Python Package Index, центральный репозиторий сторонних пакетов. Официальный сайт: pypi.org. Имеется возможность поиска через pip search <название>. Примеры популярных пакетов: requests, flask, numpy, pandas.

pip — утилита командной строки для установки, обновления и удаления пакетов. Работает она так:

pip install requests
pip install -r requirements.txt
pip freeze > requirements.txt
pip uninstall package_name

Существуют альтернативные менеджеры - conda, poetry, uv, pip-tools.

Не путайте PyPI и PyPy. PyPy - альтернатива CPython, написанная на подмножестве RPython, включающая JIT-компилятор (Just-In-Time), что даёт в 4–10 раз повышение производительности в CPU-bound задачах. Она совместима с большинством CPython-кода, однако не поддерживает все C-расширения (например, pandas работает, но медленнее).

Jython - реализация Python для JVM (Java Virtual Machine), позволяющая использовать Java-библиотеки напрямую. Нет GIL, можно использовать многопоточность Java, но отстаёт от актуальных версий Python. Как можно понять, это для интеграции с Java-системами.

IronPython - реализация для .NET Framework. Имеется интеграция с C#, ASP.NET, WPF и взаимодействие с .NET-библиотеками, для Windows-среды.

MicroPython оптимизирован для микроконтроллеров (ESP32, Raspberry Pi Pico), с минимальным объёмом памяти и поддержкой GPIO, I2C, UART. Для IoT и встраиваемых систем.