С полгода назад я начал чаще использовать для программирования Python. Почему? Конечно, из-за ИИ. Лично для меня очевидно, что сегодня эта сфера связана с очень большими деньгами перспективами во всех направлениях. А какой язык является самым распространённым для ИИ? Да-да, этот самый проныра.

Я уже писал на Python, но только небольшие скрипты. К примеру, вот этот скрейпит метаданные всех видео с моего канала на YouTube. Собранные метаданные выводятся в виде файла JSON, который я использую для показа красивой статистики роликов на этой статичной странице. Как можно видеть здесь, этот скромный скрипт через GitHub Actions выполняется в соло-режиме каждый понедельник. Просто реализовать всё это на Python куда проще, чем с помощью того же Bash. И не только из-за более дружественного синтаксиса, но и потому что его интерпретатор нативно интегрирован во все дистрибутивы Unix. Разве не круто?

Так что, да, Python силён и отлично сочетается с распространённым сегодня VSCode. Но всерьёз я начал к нему относиться лишь недавно1, когда решил заняться созданием приложений на базе ИИ (RAG, агентов, генеративных инструментов и прочего) для реальных задач. Тогда я понял, что независимо от того, нравится он вам или нет, для всего этого оптимальным выбором будет именно Python.

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

Вот лишь несколько подтверждений тому:

  1. Вокруг этого языка выстроилась полноценная экосистема библиотек и инструментов для обработки/анализа данных.2

  2. Python стал быстрее, благодаря использованию оптимизированных статических компиляторов вроде Cython.

  3. Разработчики Python проделали старательную работу, скрыв его легаси-уродство (например, __init____new__ и аналогичные искажения), сделав синтаксис более удобным для разработчиков с хорошим вкусом.

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

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

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

⚠️ Эта статья ориентирована на инструменты, с которыми работаю лично я. Если вы можете порекомендовать мне какие-то другие полезные решения, поделитесь в комментариях.

Примечание: так вышло, что моя статья набрала на Hacker News более 680 комментариев. Ещё раз убеждаюсь в непредсказуемости жизни.

Структура проекта

Я предпочитаю использовать для своих проектов Python структуру монорепозитория, включая в него и бэкенд, и фронтенд.4

Почему?

  1. Из-за сложностей с запоминанием: мне не нравится, когда части кода разбросаны по нескольким репозиториям (это явно не облегчает поиск).

  2. Наличие нескольких репозиториев зачастую излишне. Я работаю один и считаю, что если проект дорастёт до потребности его разделения на разные репозитории, это уже будет говорить о чрезмерном усложнении.

  3. Ну и я банально ленивый, стараюсь ничего не усложнять — компилирую, тестирую, пакую в контейнеры и развёртываю из одного расположения.5

Мне бы хотелось иметь инструмент, который бы генерировал структуру проекта, но пока подходящих я не нашёл. Раньше я использовал CCDS — инструмент для инициализации проектов, преимущественно в сфере дата-сайенс. Он очень хорош, но не ориентирован на фулстек разработчиков.

Вот типичная структура проекта с архитектурой фронт-бэк (чуть позже я пробегусь по каждой её части):

project/
│
├── .github/ # Рабочие потоки GitHub Actions для пайплайнов CI/CD.
│   ├── workflows/ # Каталог с файлами YAML для автоматизированных рабочих потоков.
│   └── dependabot.yml # Конфигурация Dependabot для управления зависимостями.
│
├── .vscode/ # Конфигурация VSCode для проекта.
│   ├── launch.json # Отладочные настройки для VSCode.
│   └── settings.json # Настройки проекта для VSCode.
│
├── docs/ # Сайт и документация (статичный SPA с MkDocs).
│
├── project-api/ # API бэкенда для обработки бизнес-логики и основных задач.
│   ├── data/ # Каталог для хранения датасетов и других статичных файлов.
│   ├── notebooks/ # Блокноты Jupyter для оперативных экспериментов и прототипирования.
│   ├── tools/ # Вспомогательные скрипты и инструменты для разработки и развёртывания.
│   ├── src/ # Исходный код для бэкенд-приложения.
│   │   ├── app/ # Основной код приложения.
│   │   └── tests/ # Модульные тесты для бэкенда.
│   │
│   ├── .dockerignore # Указание файлов, исключаемых из сборок Docker.
│   ├── .python-version # Указание версии Python для pyenv.
│   ├── Dockerfile # Конфигурация Docker для контейнеризации бэкенда.
│   ├── Makefile # Автоматические задачи для сборки, тестирования и развёртывания.
│   ├── pyproject.toml # Файл конфигурации проекта Python.
│   ├── README.md # Документация для API бэкенда.
│   └── uv.lock # Lockfile, содержащий список зависимостей, управляемых UV.
│
├── project-ui/ # UI фронтенда для проекта (Next.js, React и так далее).
│
├── .gitignore # Глобальный файл gitignore для репозитория.
├── .pre-commit-config.yaml # Конфигурация для pre-commit хуков.
├── CONTRIBUTING.md # Руководства для участников проекта.
├── docker-compose.yml # Настройки Docker Compose для мульти-контейнерных конфигураций.
├── LICENSE # Лицензионная информация проекта (я всегда выбираю MIT).
├── Makefile # Автоматические задачи для сборки, тестирования и деплоя.
└── README.md # Основная документация проекта (его базовые функции, процесс установки и инструкции к использованию).

Мой project представлен адресом корневого каталога и именем репозитория GitHub. Мне нравится давать проектам короткие названия длиной до 10 символов, без использования snake_case — меня вполне устраивает разделение дефисами. Заметьте, что проект должен быть самодостаточным, то есть включать документацию, инфраструктуру сборки/деплоя и любые другие необходимые файлы для его автономного развёртывания.

Важно не проделывать в project-ui никаких этапов сложной обработки данных, так как я стараюсь отделять логику фронтенда от задач бэкенда. Вместо этого я выполняю HTTP-запросы к серверу project-api, который содержит Python-код. Таким образом мы сохраняем браузерное приложение лёгким, делегируя всю основную работу и бизнес-логику серверу.

В project-api/src/app есть файл __init__.py, указывающий, что app — это модуль Python (его можно импортировать из других модулей).

Инструменты Python

uv

Для управления пакетами и сборки я использую uv. Этого инструмента мне вполне хватает для установки зависимостей и управления ими.

Вот основные команды для его настройки:

# Глобальная установка uv, если он ещё не установлен. 

curl -sSfL <https://astral.sh/install.sh> | sh

# Инициализация нового проекта (добавляет .gitignore, .python-version, pyproject.toml и так далее).

uv init   project-api

# Добавление в проект некоторых зависимостей и обновление pyproject.toml.

uv add --dev pytest ruff pre-commit mkdocs gitleaks   fastapi pydantic

# Указание в Lockfile последних версий зависимостей (создаёт .venv, если ещё не создан).

uv sync

# Активация .venv.

uv venv   activate

Обратите внимание, что самым важным для uv файлом является pyproject.toml.6 Он содержит метаданные и список зависимостей, необходимых для сборки и выполнения проекта.

Ruff

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

# Линтинг всех файлов в /path/to/code (и всех подкаталогах).

ruff check   path/to/code/ 

# Форматирование всех файлов в /path/to/code (и всех подкаталогах).

ruff   format path/to/code/

Ruff штатно поддерживает руководство по стилю PEP 8.

ty

ty — это модуль проверки типов для Python. При этом он прекрасно сочетается с typing, популярным модулем для добавления статической типизации. Думаю, что типизация реально помогает мне перехватывать ошибки типов на ранних стадиях разработки. Я не боюсь писать дополнительный код и с готовностью иду на это, если такое решение повышает качество программы, попутно уменьшая вероятность ошибок в среде выполнения.

Примечание: на момент написания статьи ty ещё находится на ранней стадии разработки, но за время использования этой утилиты я никаких ощутимых недочётов не заметил. Кстати, работают над ней ребята из Astral, той же компании, которая создала uv и ruff.

pytest

pytest — это оптимальная библиотека тестирования для Python, значительно облегчающая написание простых и масштабируемых тестов. Она поддерживает фикстуры, параметризованные тесты, а также имеет богатую экосистему плагинов. Просто создайте в project-api/src/app/tests/ файл с именем test_<unit_or_module>.py и выполните:

uv run pytest

Готово!

Pydantic

Pydantic — это библиотека для валидации данных и управления настройками. Она помогает настраивать всевозможные детали конфигурации, такие как ключи API, подключение к базе данных или параметры модели (жёсткое прописывание этих значений — очень плохая практика, если что).

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

Вот пример:

from   pydantic import BaseSettings

class Settings(BaseSettings):
    api_key: str
    db_url: str
    
    class Config:
        env_file = ".env"

settings =   Settings()

При выполнении этого кода Pydantic будет автоматически загружать значения api_key и db_url из файла .env или переменных среды. В итоге эти значения будут доступны для изменений и проверяться в соответствии с типами из модели Settings. Прекрасно!

MkDocs

С помощью MkDocs я создаю документацию и генерирую статический сайт для проекта.7 Сам я не дизайнер, поэтому предпочитаю просто копировать красивые эскизы из других опенсорсных проектов и вносить в их CSS небольшие доработки (например, изменять шрифты и цвета).

FastAPI

FastAPI я использую для создания API. Лично мне этот инструмент сильно облегчил жизнь. Он позволяет легко создавать RESTful API с автоматической валидацией, сериализацией и документацией. FastAPI построен на базе Starlette и Pydantic, благодаря чему обеспечивает превосходное быстродействие и безопасность типов. Он быстр, прост в использовании и легко интегрируется с Pydantic для валидации данных.

Dataclasses

Dataclasses — это не библиотека, а функциональность самого Python, обеспечивающая возможность определения классов, используемых в основном для хранения данных. Она предоставляет простой синтаксис для создания классов, автоматически генерирующих особые методы вроде __init__()__repr__() и __eq__().

Это существенно сокращает объём шаблонного кода при создании контейнеров данных.

Вот пример:

from dataclasses   import dataclass

@dataclass
class Point:
    x: int
    y: int

p =   Point(1,   2)
print(p)  # Вывод: Point(x=1, y=2)

Так что можно попрощаться с бойлерплейтом и загадочным кодом!

Контроль версий

GitHub Actions

Я люблю GitHub Actions, особенно за то, что эта платформа обеспечивает непрерывную интеграцию в разных ОС. Рекомендую использовать её для налаживания пайплайнов API и UI.

Вот типичный рабочий поток project-api:

name: CI-API

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - name:   Checkout code
        uses:   actions/checkout@v3
      - name:   Build Docker image
        run: docker build -t project-api:ci ./project-api
      - name:   Run tests
        run: docker run --rm project-api:ci pytest

Заметьте, что здесь для выполнения тестов в изолированной среде используется Docker.8 Изменить ОС можно через установку параметра runs-on на windows-latest или macos-latest.

Dependabot

Обработка зависимостей — это всегда боль, но Dependabot её облегчает. Он автоматически проверяет актуальность зависимостей и создаёт пул-реквесты для их обновления.

Вот образец конфигурации этого инструмента из файла .github/dependabot.yml:

version: 2
updates:

- package-ecosystem: "uv"
    directory: "/"
      schedule:
      interval:   "weekly"

Gitleaks

Думаю, что одним из основных недочётов, способных повредить нашей репутации, является сохранение чувствительных данных вроде ключей API или паролей непосредственно в репозитории. К счастью, Gitleaks помогает исключить подобные проблемы. Не вижу причин её не использовать.

Pre-commit хуки

Я использую pre-commit для выполнения проверок и форматирования кода перед отправкой коммита. Это позволяет сохранять код в опрятной форме и обеспечивать соблюдение им стандартов проекта. К примеру, я использую вот этот фреймворк для выполнения ruff-pre-commit и gitleaks перед отправкой кода в репозиторий.

Вот образец моего файла .pre-commit-config.yaml:

repos:

- repo: <https://github.com/astral-sh/ruff-pre-commit>
    rev: v0.12.3  # Версия Ruff.
    hooks:
  - id: ruff-check # Запуск линтера.
        args:   [ --fix ]
  - id: ruff-format    # Запуск форматирования.
- repo: <https://github.com/gitleaks/gitleaks>
    rev: v8.27.2
      hooks:
    - id: gitleaks

Управление инфраструктурой

Make

Make — это классическая утилита для автоматизации задач, которую можно по праву назвать мультитулом. Я с его помощью создаю простые сокращения для частых команд разработки. Вместо того, чтобы запоминать и вводить длинные выражения для выполнения тестов, сборки образов Docker или запуска сервисов, я определяю все эти задачи в Makefile. Потом остаётся просто выполнять команды вроде make test или make infrastructure-up.

Как вы могли заметить, Makefile есть в каталоге project-api и глобальном каталоге project:

1.   project/project-api/Makefile: для линтинга, тестирования и выполнения API.

2.   project/Makefile: для сборки и запуска инфраструктуры (через docker-compose).

Вот очень упрощённый пример Makefile для project-api:

DIR := . #   project/project-api/Makefile

test:
 uv run pytest

format-fix:
 uv run ruff format $(DIR)
 uv run ruff check --select I --fix

lint-fix:
 uv run ruff check --fix

Теперь, если я захочу прогнать тесты, то выполню make test, и программа запустит uv run pytest в текущем каталоге.

Для проекта в целом я использую такой Makefile:

infrastructure-build:
 docker compose build

infrastructure-up:
 docker compose up --build -d

infrastructure-stop:
 docker compose stop

make — это мощный инструмент, помогающий автоматизировать в потоке разработки практически всё. И хотя выше я привёл весьма упрощённые примеры, всегда есть возможность добавить любые сложные задачи, которые вам нужны.

Docker

Docker — это инструмент, который позволяет упаковывать приложение с его зависимостями в контейнер, включая всё необходимое для выполнения: зависимости, системные инструменты, код и среду выполнения. Работая локально, я использую Docker Compose для соединения всех образов Docker в единой сети. По аналогии с Docker, работающим с зависимостями, Docker Compose позволяет инкапсулировать весь стек приложений и отделить его от остальной локальной среды разработки.

Чтобы лучше понять этот механизм, взглянем на простой файл docker-compose.yml:

version: '3.8'
services:
  project-api:
    build:
      context:   ./project-api
      dockerfile:   Dockerfile
    ports:
      - "8000:8000"
    volumes:
      - ./project-api:/app
    environment:
      - ENV_VAR=value
    networks:
      - project-network

  project-ui:
    build:
      context:   ./project-ui
      dockerfile:   Dockerfile
    ports:
      - "3000:3000"
    networks:
      - project-network

networks:
  project-network:
      driver: bridge

Здесь мы определяем два сервиса: project-api и project-ui. Каждый из них имеет собственный контекст сборки (Dockerfile), порты, тома и переменные среды.

Вот образец Dockerfile для сервиса project-api:

FROM python:3.11-slim

# Установка системных зависимостей.

COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

WORKDIR /app

COPY uv.lock pyproject.toml README.md ./
RUN uv sync --frozen --no-cache

# Включение кода приложения.

COPY src/app app/
COPY tools tools/

# Определение команды для запуска приложения.

CMD ["/app/.venv/bin/fastapi", "run",   "project/infrastructure/api.py", "--port",   "8000", "--host", "0.0.0.0"]

Как видите, Dockerfile начинается с базового образа Python, устанавливает зависимости, копирует файлы проекта и определяет команду для запуска приложения FastAPI.

Таким образом вы можете запускать весь стек приложений одной командой:

docker compose up --build -d

Сноски

1.   Кто меня знает, тот помнит, что раньше я работал преимущественно на Java/JavaScript/R. 

2.   К примеру, сегодня Jupyter используется практически всеми ведущими облачными провайдерами в качестве штатного инструмента для интерактивной обработки данных и научных вычислений. 

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

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

5.   Я считаю, что лучше избегать преждевременного разделения. Если кодовая база содержит, скажем, 1/2 миллиона строк кода, то настройка сетевого уровня (например, вызовов API) создаст для здравомыслящих разработчиков только лишние хлопоты. 

6.   Файл pyproject.toml аналогичен package.json в Node.js или pom.xml в Java. 

7.   Кстати, я думаю, что каждый проект на GitHub должен иметь свой сайт (это очень легко реализовать через GitHub Pages), так что оправдания не принимаются. 

8. Использование Docker для непрерывной интеграции позволяет обеспечить паритет с продакшн-средами, хотя может вносить издержки на старте. Компромиссы, куда без них. 

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


  1. vadimr
    27.07.2025 09:17

    Я считаю, что лучше избегать преждевременного разделения. Если кодовая база содержит, скажем, 1/2 миллиона строк кода, то настройка связующего слоя (вроде вызовов API) создаст для здравомыслящих разработчиков только лишние хлопоты. 

    Чем он там занят, если полмиллиона строк на питоне для него – небольшой проект, в котором нет смысла париться со структурой?

    Linux 2.0 – 700 000 строк на Си.


    1. andreymal
      27.07.2025 09:17

      В оригинале там «network layer», а переводчик, видимо, играл с синонимами и проиграл


    1. Viacheslav01
      27.07.2025 09:17

      Ну так с ИИ работает, ему ЛЛМ и нагенерила все что попросил.


  1. navrotski
    27.07.2025 09:17

    Ruff не заменяет mypy и далеко не полностью заменяет pylint, так что есть смысл добавить в pre commit hooks и их.


  1. yaroslavp
    27.07.2025 09:17

    А что он там компилирует на питоныче? Или ошибка перевода?


  1. SergeiMinaev
    27.07.2025 09:17

    Разработчики Python проделали старательную работу, скрыв его легаси-уродство (например, __init__, __new__ и аналогичные искажения)

    Какая-то глупость. Это не легаси и не искажения, а фундаментальная часть дизайна языка.


  1. sci_nov
    27.07.2025 09:17

    А мне Python подходит если что-то мелкое по объему кода и не требовательное к вычислительным ресурсам (навроде одноразика). Как только объем кода повышается, то начиная с некоторого момента времени его вид становится ужасным и трудно поддерживаемым, а в классах бесит мельтешащий self.


    1. isden
      27.07.2025 09:17

      а в классах бесит мельтешащий self.

      Кмк в каждом языке есть что-то что бесит. Смиритесь, или пилите свой ЯП =)


      1. sci_nov
        27.07.2025 09:17

        Да, приходится мириться. Свой язык - не про меня, да и уже понятно, что везде есть свои плюсы и минусы)


    1. Dhwtj
      27.07.2025 09:17

      в классах бесит мельтешащий self

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

      И с какого объёма кода на питон он становится ужасный?

      Видимо, когда приходится повторно перечитать свой же код или когда становится больше одного разработчика. То есть, на проектах small+


      1. k4ir05
        27.07.2025 09:17

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

        ИМХО, при хорошем именовании, в этом нет необходимости. Только при записи атрибута в self есть необходимость. Если есть одноимённая локальная переменная, то это скорее проблема с именованием. Это и с self может вызвать путаницу. Аналогично с функцией - если её название больше похоже на состояние объекта, чем на действие, то оно, скорее всего, неудачное.


        1. Dhwtj
          27.07.2025 09:17

          Просто не делайте ошибок©

          Self частично вас страхует от них, а вы не рады


          1. k4ir05
            27.07.2025 09:17

            Ну да, делай хорошо, плохо не делай ;)

            Предпочитаю не заметать проблемы под ковёр. А такие страховки потакают плохому коду.


      1. sci_nov
        27.07.2025 09:17

        С какого объёма - не знаю, это чисто субъективная оценка.


  1. nicknamenull
    27.07.2025 09:17

    Знакомство с питоном для здравомыслящего человека заканчивается в момент выбора пакетного менеджера.


    1. S0mbre
      27.07.2025 09:17

      Какое-то странное суждение. Я спокойно пользуюсь и pip, и pipx, и poetry. Вообще без разницы. И с ума не сошёл.


    1. vvardenfell
      27.07.2025 09:17

      Там вроде еще систем сборки 3 десятка, мне страшно читать в ту сторону


    1. xenon
      27.07.2025 09:17

      Мне вообще странно, почему очень общая задача управления пакетами и структурой зависимостей везде реализуется по-своему?

      Кмк, может существовать ОДНА система пакетов, и ее должно быть достаточно для 99% случаев (по правилу Парето). И для Debian и для CentOS и для Python и для Golang и для JavaScript. Для установки пакета могут использоваться разные правила, в пайтоне одни, а в дебиане - другие, но сама идея, что если ты хочешь пакет A, то тебе нужен еще пакеты B и С и надо обновить пакет D, сейчас я их все скачаю и для каждого (в нужном порядке) вызову установку - она мне кажется очень простой.

      Я вот не понимаю, чем центос так уж принципиально отличается от дебиана-убунты, а пайтон от JS что им нужны совершенно разные системы управления зависимостями.


      1. Anton-V-K
        27.07.2025 09:17

        может существовать ОДНА система пакетов, и ее должно быть достаточно для 99% случаев (по правилу Парето)

        Правило Парето - это ж 20/80. Вот поэтому для остальных 20% случаев и нужны 80% других систем пакетов :)


  1. pnmv
    27.07.2025 09:17

    "работая в компании Х, я перешел на язык У" - это слишком банально, потому что никуда не увольнялся, а начальство дало добро. повезло, в общем.

    гораздо "интереснее"(нет), когда нужно сменить язык программирования, а потом найти работу с его применением.


    1. isden
      27.07.2025 09:17

      гораздо "интереснее"(нет), когда нужно сменить язык программирования, а потом найти работу с его применением.

      Тот самый момент, когда вот это вот самое в данный момент :(


      1. pnmv
        27.07.2025 09:17

        Это грустно. Лучше подстраховываться заранее, осваивая что-нибудь полезное, до увольнения.

        Когда-то давно, любые дополнительные навыки были плюсом, при трудоустройстве. Сейчас, почему-то, в качестве плюсов, хотят то, чем никто не владеет, а владение "чем-то не тем" считают минусом...


        1. isden
          27.07.2025 09:17

          Иногда бывает так, что это происходит внезапно. Благо есть опыт на нескольких других ЯП и в других областях =) Ну и некоторая подушка позволит спокойно отдохнуть, подкачать скиллы и вообще подумать что делать дальше.


  1. JustTry13
    27.07.2025 09:17

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


  1. 1CUnlimited
    27.07.2025 09:17

    Странно что обходится вопрос наличия для Python серверов приложений. Возьмите ту же Java - там прямо в архитектуре заложен маштабируемый сервер приложений. И когда работаешь с java понимаешь что все наработанное можно маштабировать, использовать многопоточность и т.д..

    А вот у Python мы имеем WSGI спецификацию, которая позволяет исполнять его на веб серверах. Top 6 Open Source Python Application Servers . Это конечно плюс, но Web сервер это еще не application server.

    У подозрение, что лишь простота освоения Python позволила распространится ему в ИИ. Я не понимаю как можно сделать что-то серьезное и маштабируемое, если это не имеет хорошего сервера приложений.


    1. SabMakc
      27.07.2025 09:17

      Может сервер приложений - артефакт былых времен? Навскидку, ни Golang, ни Rust не имеют сервера приложений, что не мешает создавать "что-то серьезное и маштабируемое" на них.

      P.S. к слову, за сервер приложений сейчас выступает docker (и k8s). Так что "нет сервера приложений" - очень спорно. Он просто видоизменился и стал универсальным.


    1. xenon
      27.07.2025 09:17

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

      Но как часто ваши проекты доходят до требования масштабируемости? Мне кажется, мир странным образом поделился на две половины.

      1. Есть мир "больших мальчиков", от Гугла-Амазона-Нетфликса до какого-нибудь ПФР и Россельхозбанка (и то я не уверен, что он сюда подходит). В общем, крупные фирмы, большие объемы данных, большие задачи, много серверов итд. Там где каждая задача настолько большая и сложная, что нельзя просто на одном сервере все запустить и чтоб он вытянул. И этих мальчиков - можно перечесть по пальцам (ну ок, потребуется 150-200 пальцев на всю планету, ну для математика это не проблема).

      2. Есть мир "маленьких мальчиков", там каждая задача может выполняться одним сервером. Банк-клиент для физлиц? Окей, вот один сервер под это. Банк-клиент для юрлиц? Окей, вот другой. Отдельно API для платежей, и все такое. Интернет-магазин? Ну кидайте всю статику на что-то одно (от nginx / S3 / CDN) а приложение пусть обрабатывает только покупки. У вас точно настолько успешных бизнес, что происходят сотни покупок в секунду?

      3. Есть еще промежуточная категория. Например, у нас по одному проекту серваку иногда памяти не хватает и он в OOM падает. Но мое мнение - это не "ух ты, какие у нас мощные программисты, какую сложную задачу делают!", а наоборот - остолопы не умеют писать эффективный код, поэтому там, где можно, например, сделать PDFку из кода (хватит 80286 и 1 мегабайта памяти) - запускают headless Chromium, рендерят в нем HTMLку и сохраняют как PDF.

      Я даже для одного проекта гонял тесты.... База данных вся в памяти на 1млн записей (будто бы ассортимент крупного магазина). Запросы идут по сложным критериям (смартфон, ценой ниже 500 долларов, но экран не такого-то типа и объем памяти от такого-то. Но если бренд Apple - то можно и ценой до 1500 долларов) и тупо поиск в памяти Python через evalidate - всего четверть секунды! Это самым грубым перебором всех миллионов записей, и применение фильтра к каждой. И эта задача, кстати, легко масштабируется. Но как часто задачи настолько масштабны? А что если у среднего онлайн-магазина - не миллион, а всего тысяча позиций, и покупок - не несколько в секунду, а три в день?

      Так вот ирония в том, что большинство звезд индустрии - работают в этих гигантах. Большинство инструментов создаются этими гигантами. Даже большинство "домашних" хобби-проектов когда вырастают до какого-то объема (такого, что Боинг начинает их использовать) - получают затем грант на развитие от Боинга, с его боинговскими пожеланиями, мол, у вас прекрасный продукт для проекта мощностью в 10 единиц, доработайте его чтобы он подходил нам, у нас мощность 200 000 единиц.

      Мы живем в мире, где 90% ITшников имеют маленькие задачки, лепят куличики из песочка. Но единственный экскаватор, который они могут использовать - это огромный карьерный экскаватор, а самый популярный грузовичок, чтобы возить песочек - это карьерный БелАЗ на 400 тонн. И в целом-то хорошо, что ты можешь перевезти ведерочка песка, но если потребуется - то и 400 тонн можно. Плохо - что у этого есть какая-то цена. И каждый раз пока ты автоматизируешь зоомагазин на углу - ты зачем-то платишь за ту сложность, которая позволит этому зоомагазину успешно масштабироваться завтра до масштаба Амазона и Нетфликса, кубернетесы развернуть на миллион нод, чтоб аж дата-центр трещал, но этого не случится, а затраты не вернутся.

      Не так страшна проблема, что IT-технологии недостаточно масштабируются, как то, что они излишне хорошо масштабируются.


      1. 1CUnlimited
        27.07.2025 09:17

        Ну укладывание в один сервер это уже для среднего бизнеса непросто. Вот примеры докладов на Infostart events В сообществе 1С выборы. Сегодня последний день. | 1CUnlimited | Дзен там базы от 9 до 35 терабайт. И это 1С, который конечно как кластер маштабируется, но на уровне СУБД 1 база - один инстанс СУБД. Т.е. ни шардинга ни других средств маштабирования на уровне СУБД нет. И эти примеры не единственные, вот недавно 1С тестировала 30 тыс коннектов Фирма «1С» успешно провела нагрузочное тестирование «1С:ERP Управление предприятием» на 30 000 одновременно работающих пользователей . Это не такой уж и большой по современным маштабам объем, но посмотрите на оборудование особенно в СУБД


  1. isumix
    27.07.2025 09:17

    "Решил перейти на Python" - с какого языка? Перейти можно с одного на другой.


    1. scard
      27.07.2025 09:17

      Автор про то высказался в самом - самом конце, перечислив Java/JavaScript/R ))


  1. Aodaliya_Ren
    27.07.2025 09:17

    "к продакшэну" ? Перейдите на русский, тоже не пожалеете.