Python. IT-курсы разрекламировали его как один из самых легких языков для входа в разработку, любители ИИ создают на нем свои первые нейросети, а некоторые сеньоры Java и C++ по-прежнему смотрят на него свысока, считая недостаточно строгим и производительным для «серьезной» разработки. В любом случае сегодня о Python знают все.

Поскольку заметный рост его популярности пришелся на 2010-е годы, многие считают, что язык появился сравнительно недавно. Но это неверно: Python старше большинства современных веб- и ML-фреймворков, массовой мобильной разработки и нынешнего AI-бума.

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

История Python: язык из 1989 года, который дождался своего времени

Поскольку Python стал хайповым относительно недавно, можно было бы предположить, что он был изобретен где-то в 2000-х. Но это далеко не так.

Python появился в конце 1980-х в Нидерландах. Его создатель — Гвидо ван Россум, программист из Центра математики и информатики (CWI) в Амстердаме. Он начал проектировать Python в декабре 1989 года. Первый рабочий вариант появился в 1990-м, а версия 0.9.0 была публично выпущена 20 февраля 1991 года. Название язык получил не в честь змеи, а в честь любимого британского комедийного шоу Гвидо Monty Python’s Flying Circus («Летающий цирк Монти Пайтона»).

С 2005 по 2012 гг Гвидо ван Россум работал в Google, далее в Dropbox (2013–2019). В 2019 году он ненадолго вышел на пенсию, но в 2020-м присоединился к Microsoft как Distinguished Engineer.
С 2005 по 2012 гг Гвидо ван Россум работал в Google, далее в Dropbox (2013–2019). В 2019 году он ненадолго вышел на пенсию, но в 2020-м присоединился к Microsoft как Distinguished Engineer.

Непосредственной причиной появления языка был проект Amoeba. Это экспериментальная микроядерная распределенная операционная система, разрабатывавшаяся CWI и Vrije Universiteit Amsterdam: она должна была представить сеть рабочих станций, файловых серверов и пула процессоров как единую вычислительную систему с прозрачным размещением программ и данных.

Для Amoeba требовались системные административные утилиты. Писать их на C было слишком трудоемко, а Bourne shell оказался недостаточно удобен для работы с механизмами новой распределенной операционной системы. По словам самого ван Россума, потребовался язык, который мог бы «закрыть разрыв между C и shell». На дизайн Python также существенно повлиял язык ABC, над которым ван Россум ранее работал в CWI.

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

Когда Python начал расти

У Python не было одного переломного года. Он постепенно распространялся в автоматизации, веб-разработке, образовании и научных вычислениях, после чего в 2010-х его рост заметно ускорили data science и machine learning.

Анализ Stack Overflow за 2017 год показывал, что в странах с высоким уровнем дохода рост посещаемости тега Python ускорялся начиная с 2013 года. В июне 2017-го Python впервые стал там самым посещаемым тегом среди языков, а его посещаемость с 2012 года увеличилась примерно в 2,5 раза. За пределами этой группы стран выраженный рост, по данным той же работы, начался примерно в 2014 году. Но нужно учитывать, что это статистика просмотров Stack Overflow, а не прямое измерение объема промышленного кода.

В опросе Stack Overflow 2019 года Python обошел Java по доле респондентов, использовавших язык, и был снова назван самым быстрорастущим крупным языком. По состоянию на июль 2026 года Python занимает первое место в TIOBE с рейтингом 18,94%, опережая C, C++, Java и C#.

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

Таким образом, машинное обучение стало одним из основных драйверов роста Python, но не единственным. Существенную роль также сыграли автоматизация, образование, веб-разработка, научные вычисления и общее расширение open source-экосистемы.

Почему развитие нейросетей вывело Python в лидеры

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

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

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

На практике схема выглядит так:

  1. CPython выполняет пользовательский код и доходит, например, до вызова torch.matmul() или слоя nn.Linear.

  2. Python-интерфейс передает вызов внутренней реализации библиотеки.

  3. Библиотека выбирает подходящий вариант операции для CPU или GPU.

  4. Вычисления выполняет скомпилированный код: C, C++, Fortran, CUDA либо специализированная математическая библиотека.

  5. Python получает объект с результатом и продолжает выполнение программы.

В документации PyTorch прямо указано, что Python-интерфейс передает в C++ практически все вычислительно тяжелые операции, особенно численные. Поэтому основную часть времени программа может проводить не внутри интерпретатора Python, а в оптимизированных CPU- или GPU-ядрах.

Почему тогда не выполнять всю работу на самом Python? Проблема проявляется прежде всего в коде, который последовательно обрабатывает отдельные Python-объекты. CPython выполняет байткод, определяет типы во время работы программы и несет дополнительные расходы при каждой операции. Поэтому цикл на чистом Python обычно значительно медленнее аналогичного цикла, скомпилированного из C++.

В исследовании USENIX ATC 2022 на наборе тестов LangBench приложения под CPython выполнялись в среднем в 29,5 раза медленнее соответствующих C++-реализаций. Это не универсальный коэффициент для любого кода и не сравнение скорости обучения нейросетей: результат относится к конкретному набору из двенадцати тестов. Он показывает, насколько заметными могут быть накладные расходы CPython, когда основная работа действительно выполняется интерпретатором.

В ML-нагрузках ситуация часто иная. Один вызов Python может запускать перемножение матриц, состоящих из миллионов элементов. Накладные расходы возникают при вызове операции, а вся тяжелая математика выполняется внутри нативного ядра. В результате Python позволяет быстро описывать и проверять гипотезы, одновременно передавая вычислительно сложные задачи C++, CUDA и специализированным библиотекам. Именно сочетание высокой скорости разработки на Python с возможностью передавать ресурсоемкие операции оптимизированным библиотекам и GPU сделало его особенно удобным инструментом для нейросетей и помогло занять лидирующее положение в ML-экосистеме.

Экосистема и сетевой эффект

Когда есть удобный язык, под него пишут библиотеки. А когда библиотек много, его используют еще больше.

К середине 2010-х вокруг Python сформировалась полноценная среда для научных вычислений и анализа данных. NumPy отвечал за работу с многомерными массивами, SciPy — за численные методы, pandas — за табличные данные, scikit-learn — за классические алгоритмы машинного обучения, а Matplotlib — за визуализацию. Связка IPython и Jupyter позволяла запускать код по частям, добавлять формулы, графики и пояснения в одном документе. При этом Jupyter — не Python-библиотека, а платформа, поддерживающая разные языки, хотя именно Python стал одним из ее основных сценариев использования.

Поэтому, когда Google открыл исходный код TensorFlow в ноябре 2015 года, а Facebook AI Research представила PyTorch в январе 2017-го, новые фреймворки пришли уже в зрелую экосистему. Их пользователи могли работать с привычными инструментами подготовки данных, визуализации и анализа, а вычислительно сложные операции выполнялись внутри фреймворков с помощью C++, CUDA и специализированных библиотек.

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

Почему Python оказался удобным интерфейсом для ML

Машинное обучение находится на пересечении программирования, математики, статистики и конкретной предметной области. Многие дата-сайентисты и ML-исследователи приходят из физики, биологии, экономики или прикладной математики. Их основная задача — сформулировать гипотезу, подготовить данные, изменить архитектуру модели и оценить результат, а не вручную управлять памятью или реализовывать матричные операции.

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

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

Гибкость Python и eager-режим PyTorch дают исследователю больше свободы: можно быстро менять структуру модели, использовать обычные условия и циклы, выводить формы тензоров и проверять отдельные части вычислений. Отдельно работает autograd: во время прямого прохода он формирует граф вычислений для поддерживаемых операций, а вызов backward() автоматически рассчитывает градиенты, поэтому производные для каждого слоя обычно не приходится реализовывать вручную.

В итоге, к моменту распространения deep learning вокруг Python уже существовала развитая среда для работы с массивами, научными алгоритмами, табличными данными, визуализацией и интерактивными ноутбуками. Новым ML-фреймворкам не требовалось создавать весь инструментарий с нуля: они могли встроиться в уже привычный для исследователей рабочий процесс.

Это не означает, что C++ не используется дата-сайентистами и ML-инженерами. На нем пишут внутренние компоненты фреймворков, собственные операторы, высокопроизводительные пайплайны и системы с жесткими требованиями к задержкам. У PyTorch существует полноценный C++-интерфейс для обучения и запуска моделей без Python. Однако сами разработчики PyTorch рассматривают его как дополнение к Python-интерфейсу для случаев, когда этого требуют производительность, многопоточность или условия развертывания.

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

Как это работает в коде

Код ниже показывает, как Python запускает обучение нейросети, а тяжелые вычисления передает внутренним компонентам PyTorch, написанным на C++ и CUDA. Профилировщик помогает увидеть, какие операции выполняются за обычными вызовами Python.

import torch
import torch.nn.functional as F
from torch import nn
from torch.profiler import ProfilerActivity, profile, record_function


torch.manual_seed(42)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

batch_size = 512
input_dim = 1024
hidden_dim = 2048
num_classes = 100

# Синтетический batch: его размера достаточно,
# чтобы матричные операции были заметны в профиле.
features = torch.randn(batch_size, input_dim, device=device)
labels = torch.randint(
    low=0,
    high=num_classes,
    size=(batch_size,),
    device=device,
)

classifier = nn.Sequential(
    nn.Linear(input_dim, hidden_dim),
    nn.GELU(),
    nn.Linear(hidden_dim, num_classes),
).to(device)

classifier.train()

optimizer = torch.optim.SGD(
    classifier.parameters(),
    lr=1e-2,
)


def train_step() -> torch.Tensor:
    """Один шаг обучения: forward, backward и обновление весов."""
    optimizer.zero_grad(set_to_none=True)

    # Python вызывает слои модели, а операции над тензорами
    # передаются внутренним операторам PyTorch.
    logits = classifier(features)
    loss = F.cross_entropy(logits, labels)

    # Autograd запускает обратный проход и рассчитывает градиенты.
    loss.backward()
    optimizer.step()

    return loss.detach()


# Прогрев исключает часть разовых расходов
# на первоначальную инициализацию.
for _ in range(3):
    train_step()

if device.type == "cuda":
    torch.cuda.synchronize()


activities = [ProfilerActivity.CPU]

if device.type == "cuda":
    activities.append(ProfilerActivity.CUDA)


with profile(activities=activities) as profiler:
    with record_function("training_step"):
        loss = train_step()

    # CUDA-операции выполняются асинхронно.
    # Перед формированием таблицы дожидаемся их завершения.
    if device.type == "cuda":
        torch.cuda.synchronize()


sort_key = (
    "device_time_total"
    if device.type == "cuda"
    else "cpu_time_total"
)

print(f"device={device}, loss={loss.item():.4f}")

print(
    profiler.key_averages().table(
        sort_by=sort_key,
        row_limit=15,
    )
)

В конце программа выводит таблицу профилировщика. В ней обычно видны операции aten::linear, aten::addmm и aten::mm, которые отвечают за работу слоев и матричные вычисления. Python задает порядок действий, а сами расчеты выполняются оптимизированным кодом на процессоре или видеокарте.

Это не полноценный тест производительности: код профилирует только один шаг обучения, а сам профилировщик немного замедляет выполнение. Вызов torch.cuda.synchronize() нужен, чтобы перед выводом таблицы дождаться завершения всех операций на видеокарте.

Заключение

Python может уступать компилируемым языкам в скорости выполнения чистого CPU-кода, но для нейросетей это оказалось не главным. Он позволяет быстро описывать модели и проверять гипотезы, а ресурсоемкие операции передает оптимизированным библиотекам и GPU-ядрам. В сочетании с развитой научной экосистемой именно это сделало Python основным интерфейсом современной ML-разработки.

Комментарии (2)


  1. mixsture
    22.07.2026 19:09

    думаю, python зашел в ML даже не из-за особенностей языка, а из-за python jupiter notebook:

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


  1. maxscitech
    22.07.2026 19:09

    Почему он взлетел - Совершенствовалось железо и стало наплевать на скорость и прожорливость, соответственно из-за простоты освоения, развития интернета (где можно получить документацию на модули) и "всего готового" в языке + быстрая "разработка" для "заработка" появилась куча скрипт-киддисов (которые ныне называют себя "программистами") и пошло поехало.