Python backend. Вид изнутри — Ключевые аспекты веб-разработки на Python
Из чего состоит backend?
Когда сервер получает запрос от браузера, с программной стороны его обрабатывает Web-сервер. Некоторые языки встраивают web-сервер прямо в своё приложение, но большинство интерпретируемых языков использует специальную внешнюю программу. Таких самостоятельных Web-серверов существует несколько, но наиболее популярен Nginx. Он берёт на себя обработку входящих запросов, отдачу статических файлов, распределение запросов между web-приложениями.
В случае Python за web-сервером как правило находится WSGI-сервер, запускающий WSGI-приложения. WSGI или Web Server Gateway Interface — это такая абстракция, согласно которой ответчик на запросы, это Python-функция, принимающая запрос и возвращающая ответ! Звучит просто, не правда ли? Минимальное WSGI-приложение выглядит примерно так:
Web-фреймворк
Показанное Web-приложение пусть и работает, но на любой запрос оно будет возвращать один и тот же текст. Что-то более сложное написать в таком стиле будет проблематично, пусть и выполнимо. Чтобы упростить жизнь типичного backend-разработчика и помочь ему реализовывать типичные приложения, используются фреймворки (frameworks) — библиотеки, задающие готовую структуру приложения. В эту структуру разработчику нужно только вписывать свои кусочки кода, а сам «скелет» приложения оказывается сразу готов к применению. Именно Web помогают писать web-фреймворки. Самые популярные web-фреймворки для Python — это Django и Flask.
Web-фреймворки берут на себя маршрутизацию, упрощают работу с заголовками и данными запросов, формирование ответов в разных форматах, сохранение истории запросов в файлы (для анализа и сбора статистики, для нужд отладки).
ORM и шаблонизатор
Что же ещё находится в бэкенде, кроме машинерии обработки запросов? Чаще всего — ORM и шаблонизатор.
ORM или Object-Relational Mapping, это средство работы с записями в базах данных (БД), представляющие записи в виде понятных для языка программирования объектов.
Пишем приложение с бэкендом на Django и фронтендом на React
Автор перевода Полина Ревякина, копирайтер в Skillbox
В этом материале вы узнаете:
Подготовка Создаём проект Django в виртуальном окружении Python
Создайте новую папку и перейдите в неё:
Потом активируйте виртуальное окружение Python:
Примечание все следующие команды нужно выполнять из папки django-react и с активированным виртуальным окружением.
Установите зависимости Джанго и Django REST Framework:
pip install django djangorestframework
После установки создайте новый проект Django:
django-admin startproject django_react
Теперь сделаем API на Django для создания и хранения контактов.
Пишем приложение с бэкендом на Django
В каждом проекте Django может быть много приложений. Приложения можно делать переиспользуемыми: такими, что их можно добавить в менеджер пакетов Python и установить через него в другой проект, в котором нужно такое приложение.
27–29 декабря, Онлайн, Беcплатно
Для создания нового приложения Django используется команда:
django-admin startapp app_name
где app_name — название приложения.
В нашем случае команда будет выглядеть так:
django-admin startapp leads
Теперь сделаем так, чтобы Django проект использовал новое приложение. Откройте файл django_react/settings.py и добавьте приложение в INSTALLED_APPS :
Создаём модель в базе данных с Джанго
Модель — это объект, представляющий собой данные из таблицы. Почти каждый веб-фреймворк использует модели, и Django — не исключение. Она может иметь одно или больше полей. Каждое поле соответствует полю в таблице.
Мы собираемся хранить контакты, поэтому модель Lead может состоять из этих полей:
Добавим ещё поле со временем создания модели, потому что по умолчанию Django этого не делает.
Откроем leads/models.py и опишем модель Lead :
Примечание изучите документацию Django о полях. Когда придумываете структуру модели, выбирайте самые подходящие для вашего случая поля.
Создадим миграции командой:
python manage.py makemigrations leads
и применим их к базе данных:
python manage.py migrate
Займёмся тестированием
Вы могли подумать «А как же тестирование?».
Существует масса туториалов по бэкенду на Джанго, начинающихся примерно так:
Не надо так. Нет никакого смысла ни в тестировании стандартной модели Django, ни в тестировании Django ORM. Что точно не нужно тестировать при создании приложения с бэкендом на Django:
Не тестируйте то, что уже протестировано! Так что же тогда тестировать?
Добавили свой метод в модель Django — протестируйте его. Дополнили стандартное представление — протестируйте его. Но как узнать, что именно нужно протестировать?
Узнать это поможет библиотека coverage. Установите её:
pip install coverage
Теперь после каждого добавления или изменения кода запускайте coverage :
и создавайте отчёт:
Вы увидите, что именно нужно протестировать. Если предпочитаете увидеть отчёт в командной строке, запустите команду:
Сериализаторы Django
Сериализация — это конвертация объекта Python в другой формат. После сериализации можно сохранить объект в файл или послать его через сеть.
Почему сериализация необходима? Модель Джанго — это класс Python. Чтобы превратить её в данные в формате JSON, нужна сериализация.
Сериализаторы работают и в обратном направлении: они конвертируют JSON в объекты. Это позволяет:
Суммируя: сериализаторы в Django можно использовать для совершения операций с моделями Django через API.
Создаём представления
Если вы раньше работали с другими фреймворками, то можете удивиться, что в Django нет контроллеров.
Контроллеры содержат логику обработки запросов и возвращения ответов. В традиционной архитектуре MVC есть модель (Model), представление (View) и контроллер (Controller). Примеры MVC фреймворков: Rails (Ruby), Phoenix (Elixir), Laravel (PHP).
Django — это фреймворк MVT. MVT — это модель, представление и шаблон (Template). В Django есть много типов представлений: функции-представления, представления, основанные на классах, и обобщённые представления.
Используйте функции-представления только если изменение обобщенных представлений займет больше, чем написание представления заново.
Мы будем использовать обобщённые представления. Наше простое приложение будет:
Добавьте в файл django_react/views.py следующий код:
С помощью трёх строк кода мы создали представление для обработки GET и POST запросов.
Чего ещё не хватает? Маршрутизации URL. Другими словами, нам нужно соединить URL и представления.
Настраиваем маршрутизацию url
Запустим сервер Django:
python manage.py runserver
Перейдите по url http://127.0.0.1:8000/api/lead/ и вы увидите API:
Примечание в продакшене лучше отключить возможность просмотра API. Это можно сделать в конфигурации:
Соединяем Django и React
У многих разработчиков возникают вопросы по поводу того, как правильно соединить Django и React.
Должен ли роутер React взять на себя маршрутизацию? Нужно ли монтировать компоненты React в каждом шаблоне Django?
Ответ зависит от случая.
Есть следующие способы создания проекта на Django и React (они похожи почти для любого веб-фреймворка):
Если вы только начали работать с Django REST и React, избегайте варианта 2. Вместо этого выберите 1 (React в собственном приложении Django для фронтенда), если:
Если будете держать React близко к Django, то будет проще с авторизацией. Можно будет использовать встроенную систему авторизации Django для регистрации и входа пользователей. Используйте старую добрую авторизацию с помощью сессий и не беспокойтесь о токенах и JWT.
Выберите вариант 3 (смешанный вариант: мини-приложения React в шаблонах Django), если:
В данной статье мы будем использовать вариант 1.
Устанавливаем React и webpack
Создадим новое приложение Django для фронтенда:
django-admin startapp frontend
Вы увидите новую папку с названием frontend в вашей структуре папок:
Подготовим папки для хранения компонентов React:
Дальше установим React, webpack и babel. Перейдите в папку frontend и создайте окружение:
Установите webpack и webpack CLI:
Откройте package.json и запишите 2 скрипта для продакшна и для разработки:
Сохраните и закройте файл.
Установим babel, чтобы код был совместим со старыми браузерами, которые не поддерживают последние стандарты JavaScript:
Настроим Babel (по-прежнему находясь в папке frontend ):
Создадим файл webpack.config.js для настройки загрузчика babel:
Готовим приложение Django для фронтенда
Зайдя на http://127.0.0.1:8000/, вы увидите пока что просто пустую страницу (для этого сервер Django должен продолжать работать).
Фронтенд на React
После бэкенда, написанного на Джанго, сделаем простой компонент React, который будет отображать наши данные. Если ваша база данных пуста, то самое время наполнить приложение какими-нибудь данными.
Запустите сервер Django и перейдите на http://127.0.0.1:8000/api/lead/ чтобы добавить контакты.
import App from «./components/App» ;
Теперь можно протестировать результат. Запустите webpack:
Запустите сервер Django:
python manage.py runserver
Перейдите на http://127.0.0.1:8000/. Если вы видите сообщение «Что-то пошло не так», то убедитесь, что применили миграции и заполнили базу данных. Вы должны увидеть данные, отображенные компонентом React.
Выглядит просто. И работает!
Заключение
В этом материале мы сделали простой проект на Django REST API и React. Мы научились:
Если этот проект показался сложным, попробуйте другой туториал. В нём мы показали, как создать первое веб-приложение на Django.
Python и веб-разработка: краткое руководство
Jun 22 · 7 min read
За последние несколько лет популярность Python резко возросла, и он даже превзошел Java. С развитием машинного обучения, анализа данных и веб-приложений многие разработчики стали чаще использовать данный язык программирования, так как он обладает множеством полезных библиотек, простым синтаксисом и мобильностью. Без сомнения, сейчас наиболее подходящее время, чтобы научиться работать с Python.
Итак, в данной статье мы ответим на следующие вопросы:
Веб-разработка — что это?
Почему Python подходит для веб-разработки?
Преимущества разработки веб-приложений в Python:
Другие языки программирования для веб-разработки:
Веб-фреймворки Python
Что такое фреймворки и почему они так важны? Веб-фреймворк — это набор пакетов и модулей, состоящих из предварительно написанного стандартизированного кода. Таким образом, код обеспечивает разработку веб-приложений, делая этот процесс быстрее и проще, а программы более надежными и масштабируемыми. Другими словами, фреймворки уже обладают встроенными компонентами, которые упрощают вашу работу над проектом.
Веб-фреймворки Python используются только в бэкенде для серверных технологий, помогая в маршрутизации URL-адресов, HTTP-запросах, доступе к базам данных и веб-безопасности. Фреймворк не считается обязательным, однако мы рекомендуем использовать его, так как он поможет разработать сложные приложения за достаточно короткое время.
Какие веб-фреймворки Python наиболее популярны?
Django — это быстрый, безопасный и масштабируемый веб-фреймворк Python, который предлагает высокий уровень и открытый исходный код. Django обладает мощной поддержкой сообщества и подробной документацией.
Фреймворк включает комплексный пакет, в котором вы получите панель управления, интерфейс базы данных и структуру каталога после создания приложения. Кроме того, он включает большое количество функций, поэтому вам не придется добавлять отдельные библиотеки. Аутентификация пользователей, механизм шаблонов, маршрутизация, миграция схемы базы данных и т.д. — все это примеры возможностей, которые предлагает фреймворк.
Django отличается гибкостью. Он позволяет работать как с минимально жизнеспособным продуктами, так и с более развитыми компаниями. Instagram, Dropbox, Pinterest и Spotify — все эти компании также используют Django.
Flask считается микрофреймворком, который представляет минималистичный веб-фреймворк. Но по сравнению с Django он не обладает такими функциями, как механизм веб-шаблонов, авторизация учетной записи и аутентификация.
Flask отличается простотой в использовании. Поэтому вы можете добавить расширения и библиотеки, которые вам нужны при написании кода.
Идея Flask заключается в том, что данная платформа предоставляет только компоненты, необходимые для создания приложения. Некоторые функции включают встроенный сервер разработки, отправку запросов Restful, обработку Http-запросов и многое другое. Flask также является распространенным и мощным веб-фреймворком, поскольку он используется крупными компаниями, такими как Netflix, Linkedin и Uber.
Другие известные фреймворки
Возможно, вы зададите вопрос — какой же фреймворк стоит выбрать? Но мы не сможем дать вам однозначный ответ. Для начала, оцените свой уровень веб-разработчика. Если вы обладаете большим опытом, то стоит отдать предпочтение продвинутым программам. Однако, если вы начинающий разработчик, то попробуйте использовать фреймворк со встроенной технической поддержкой, например Django.
Кроме того, спросите себя, хотите ли вы создать «основополагающую» кодовую базу или же сформировать её основы? Если вы предпочитаете первый вариант, то стоит использовать Django, а если второй, то Flask. Но стоит отметить, что оба инструмента обладают одинаковой функциональностью.
Библиотеки Python для веб-разработки
Ниже представлено несколько полезных библиотек Python для веб-разработки:
Дорожная карта для веб-разработки с использованием Python
Шаг 1:HTML + CSS
В начале веб-разработки стоит изучить HTML и CSS, которые являются основой обучения при создании сайтов. Гораздо важнее научиться структурировать адаптивные статические страницы, чтобы начать свой путь веб-разработки. Также полезно узнать про такие понятия, как Интернет, HTTP, браузер, DNS, хостинг и многое другое.
Вы можете также изучить такие CSS-фреймворки, как Materialize или Bootstrap. Они значительно ускорят вашу работу.
Шаг 2: Javascript
Следующий шаг, который необходимо сделать — это изучить Vanilla Javascript. Вам стоит ознакомиться с такими базовыми концепциями, как типы данных, переменные, общие соглашения, работа со строками, арифметика, управляющие операторы, циклы и т.д. Знание этих основ упростит применение Javascript к коду на стороне клиента.
Шаг 3: DOM & jQuery
Затем вам стоит научиться управлять еще одной библиотекой Javascript — jQuery. С ее помощью процесс манипулирования DOM станет гораздо проще. Теперь у вас есть представление о том, как создать динамические страницы.
Фронтенд-фреймворк
Для создания функционального веб-приложения с полным стеком рекомендуется изучать фронтенд-фреймворк. Такой навык часто является обязательным требованием при найме front-end или full-stack разработчика.
Шаг 4: Python
Теперь перейдем к бэкенду. Прежде чем приступить к манипуляциям с DOM, необходимо знать основы Python и Javascript. Эти базовые знания подготовят вас к Django. Изучение Python не вызывает трудностей, так как многие концепции напоминают Javascript.
Шаг 5: База данных Django +
С помощью Django вы сможете настроить бэкенд-среду и сформировать бизнес-логику. Вам также стоит узнать о том, как создать запросы, изучить базу данных SQLite и CRUD- функцию. В таком случае, вы сможете разработать приложение с полным стеком.
Как создать первое веб-приложение в Python
Запустите приложение Flask «hello world» в качестве введения в веб-фреймворки Python
Установка Flask
Первое, что необходимо сделать — это установить Flask. В зависимости от вашей версии Python, вам придется использовать pip или pip3.
Приложение Flask
Затем, создайте файл под названием hello.py со следующим кодом:
Заключение
Теперь вы имеете представление о том, как использовать Python для веб-разработки. Однако обучение на этом не заканчивается. Поэтому продолжайте искать надежные ресурсы, онлайн-курсы и практические проекты, чтобы улучшить свои навыки.
Python — серьезный язык для разработки backend
Всем привет! Меня зовут Денис Аникин, я тимлид в команде Chat в Райффайзенбанке. А также представитель внутреннего Python-сообщества, так называемый «community lead» (об этом как-нибудь в другой раз). В этой статье я хотел поговорить про отношение к Python среди разработчиков и обсудить все основные претензии, которые очень давно следуют за языком по пятам.
В начале я хочу коротко рассказать про причины этой статьи — она не претендует на статус серьезного исследования, статья, скорее, немного ироничная. И возникла она как ответ на бесконечные камни, летящие в сторону моего любимого языка.
Я часто принимал участие в больших дискуссиях, действительно ли Python можно назвать серьезным языком программирования. Именно это, во многом, и стало причиной для написания этой статьи. Здесь я хочу попытаться донести идею, что как минимум для меня Python — действительно серьезный, без всяких скидок, язык программирования. Заодно я хочу воодушевить тех, кто уже пишет на Python, но начал немного стесняться этого, начитавшись интернета.
Также я вспоминаю нашу внутреннюю шутку, которая сформулирована моим коллегой, Даниилом: «Денис начинает свой понедельник с очередного доклада на тему, почему Python — серьезный язык». Я долго думал над этой шуткой (извините, я не гений), а потом решил: почему бы и не начать с этого статью? 🙂
Поэтому я хочу поговорить про проблемы Python и обсудить накопившиеся к нему основные претензии.
Динамическая типизация
За динамическую типизацию Python ругали практически все — это одна из крупнейших претензий к нему в среде разработчиков. Но на самом ли деле динамическая типизация — такое уж зло? Как минимум, разработка на языках динамической типизации проще, быстрее и зачастую приятнее — конечно, это субъективный тезис, но он имеет право на существование.
Какой-нибудь JSON-парсер на языке со статической типизацией будет гораздо более многословным и тяжелым в написании, чем на языке с динамической типизацией (ох уж эта элегантная связка orjson и pydantic). Где-то, где мы в Python отобьемся манипуляциями в рантайме, придется подтаскивать большие объёмы кодогенерации.
Аннотации — благо
При этом у динамической типизации есть минусы. Например, нам приходится писать больше тестов, у нас может быть больше ошибок в рантайме при некоторых условиях. У нас динамическая типизация, поэтому до запуска понять, что с типами проблема, мы не сможем. И вроде бы статическая типизация здесь выигрывает.
При этом Uncle Bob говорил, что тесты на бизнес-логику не отменяются статической типизацией, да и в Python теперь типы можно проверять статически с помощью аннотаций и MyPy. Конечно, мы пишем больше тестов и тщательно проверяем бизнес-логику, но, на мой взгляд, это идет на пользу сервисам. Всё очень неоднозначно.
Да, у нас есть gradual типизация. MyPy, typing, аннотации типов — это позволяет нам значительно улучшить качество кода, уберечься от массы ошибок, получить экстрафункциональность языка. Например, в Python нет констант, но с помощью связки typing и MyPy можно получить их аналог. Аннотации в Python можно анализировать как статически, так и динамически: в typing есть интроспекция, появляются проекты вроде Beartype.
На базе аннотаций типов построены современные фреймворки, такие как Pydantic (строгие схемы валидации в рантайме) или FastAPI. Я считаю вот так: Python в связке с аннотациями типов являет нам gradual типизацию и тем самым предоставляет здоровый компромисс между преимуществами динамической и статической типизаций. Он не порождает хтоническое чудовище, каким его часто объявляют в интернете. Напротив, нам дают способ писать и быстро и надежно, здесь и сейчас.
Где-то тут к нам подкрадывается вопрос о типобезопасности. Полагаю, что аннотации типов проверку на типобезопасность не пройдут, хотя вопрос это довольно сложный, не для моего уровня понимания. На текущий момент ошибок типов с MyPy и аннотациями типов я не встречал, но уверен, что где-то при определенном стечении обстоятельств это возможно. Единственное, что видно у нас — увеличение надежности нашего кода (пока мы пишем наши бэкенды, аннотации часто помогают отлавливать ошибки), умение гибридно использовать аннотации и почти никаких type error в коде.
Также стоит вспомнить, что люди, предпочитающие статическую типизацию, часто говорят, что для маленьких проектов динамическая типизация «не страшна», а на действительно больших мы начинаем чувствовать её недостатки.
Честно говоря, пункт уже раздулся, поэтому я просто набросаю свои мысли списком:
Статический анализ хорош везде;
Как мы уже сказали выше, в Python есть статистический анализ, пускай и немного уступающий «настоящему» выводу типов — «настоящей» типобезопасности. Мы используем его в полный рост, и с ним можно писать действительно большие проекты
Мы живем в эпоху, когда микросервисная архитектура очень популярна, поэтому проблема проектов в сотни тысяч и миллионы строк кода уже не так сильна. И накал претензий к динамической типизации, соответственно, куда ниже. Даже если мы их принимаем.
Скорость
Этот аспект языка часто подвергается критике очень многими разработчиками. И если динамическая типизация — сложная и неоднозначная тема для обсуждения, то скорость — то, о чем говорят вообще все.
Если посмотреть на синтетические бенчмарки, то Python часто можно обнаружить в самому низу турнирных таблиц. Многие разработчики считают это Ахиллесовой пятой Python, что не может не сказываться на восприятии языка
Когда обсуждают скорость Python, обычно вспоминают про C++, ведь на нем все бенчмарки выглядят в сто раз лучше, чем на Python. Но если мы начнём разбираться в вопросе, то станет ясно, что скорость Python на данном этапе — не такая уж проблема. Конечно, Python действительно медленный в CPU-bound задачах. И тут у вас в голове возникает мысль — если он такой медленный, то это точно проблема!
На мой взгляд, дело обстоит так. В современной web-разработке полно i/o-bound нагрузки: часто мы принимаем запросы по сети, отправляем их в сеть, читаем из БД, пишем в БД, оперируем с файлами и так далее.
Одни из действующих «лиц» CPU-bound и IO-bound задач
Для этого типа задач у Python есть прекрасный ответ — асинхронный подсет языка, нативный async/await, event loop из коробки и uvloop, для тех, кто хочет ещё быстрее. С помощью этой части Python мы можем эффективно утилизировать ресурсы CPU. А для исключительно CPU-bound в мире Python тоже много «припарок»: multiprocessing, subprocess, Pypy, Cython, Numba и так далее. Поэтому асинхронный Python работает очень даже быстро.
Подведу субъективный итог: многое, если не всё, можно смело писать на Python, а CPU-bound, при необходимости (если стандартная библиотека не тянет), переписывать на более быстрых языках и ставить эти микросервисы-воркеры за очередями сообщений. Разве это не идеальное сочетание?
Язык для новичков
Довольно часто Python считают языком для новичков. Ему учат на каждом шагу, в мире миллион курсов по Python. Топовые блоггеры обещают обучить ему чуть ли не за один вечер, говорят, что все сразу же получают серьезную зарплату, уютный офис и счастливое будущее. На этом слишком радужном фоне за Python прочно закрепился имидж языка для новичков, где достаточно написать пару for и def, объявить несколько переменных — и вот ты уже профессиональный Python-разработчик уровня middle. А потом «перерастаешь» и идешь писать на «серьезном языке».
Это все какой-то интернет-морок, потому что Python, как и любой другой язык, требует освоения, изучения, времени.
В самом языке у нас целая куча всяких знаний, нюансов, сложностей и декларативных частей. Судите сами:
У нас есть протокол итерации. Конечно, можно сказать, что итератор — не совсем часть функционального программирования, что итераторы есть и в других языках. Но я хочу подчеркнуть, что итераторы — это не совсем просто, особенно вначале, особенно когда нам нужно реализовывать свои.
Декораторы. Здесь тебе и функции высшего порядка, замыкания, три уровня вложенности для параметризированных декораторов — слишком много всего для такого «простого» языка. Я сам по началу долгое время не понимал паттерн «декоратор», с трудом писал их. И я знаю, что у многих с этим есть проблемы, это видно как минимум на собеседованиях.
Метаклассы. Классы, создающие классы? Функция type, она же класс? А тип type — тоже type? Все классы создаются type? Популярный сценарий применения — ORM? Можно, пожалуйста, мне другой «простой» язык?
Библиотека functools в полном составе 🙂
Генераторы. Можно спрашивать на собеседованиях: «А для чего вы используете генераторы?» — и услышать очень много разных ответов. Некоторые вообще не понимают, зачем они нужны. А ведь генератор поддерживает протокол итерации, в него можно слать значения, yield from — ну, сами все понимаете.
Контроль зависимостей. Venv, virtualenv, pipenv, poetry, pip tools, pdm, pipx, pyproject и так далее.
Инфраструктура вокруг Python. Крайне полезно для работы было бы знать, что такое pypa, pypi, psf — а это ещё отдельный пласт знаний.
PEP. Иногда спрашиваю людей: «А что такое PEP?», — и самый частый ответ: «Стандарт кода». Даже опытные разработчики помнят PEP8 в лучшем случае.
Около сотни магических методов. Хорошо было бы в них просто ориентироваться.
Могущественная интроспекция и «мета-язычные» вещи. Runpy, importlib, trace, traceback, gc, inspect, sys, typing.get_type_hints, typing.get_origin, typing.get_args.
Новые вещи. Оператор «морж», pattern matching.
Конкурентное выполнение. Threading с кучей нюансов, multiprocessing, subprocess, свежий communicating sequential processes «паттерн» (PEP 554).
GIL. Комментарии не нужны, но они будут (я не умею лаконично, помогите).
Особые языковые возможности. Dict, list, set comprehensions, generator expressions, например.
Асинхронность. Это отдельный «подсет» языка, где уже целая своя вселенная с кучей пакетов и даже отдельными (не встроенными в язык) концепциями, вроде structured concurrency.
Аннотации типов. Или аннотированный Python — тоже, считай, свой мини-«подсет» языка, вводящий новый понятийный аппарат, и новый вид типизации — структурную саб-типизацию, ближайшим аналогом которой из мира динамической типизации можно было бы назвать утиную.
Динамическая типизация. Строгая (местами «обходимая» полимформизмом, или неявным приведением int к float), утиная типизация, typing.Protocol (про него выше), gradual типизация. Скажите мне — это правда так просто?
Типичный диалог (а иногда и монолог) в интернете
И я бы мог ещё продолжать какое-то время. Этот список я составил не для того, чтобы отпугнуть от языка, но мне хочется продемонстрировать, что Python — не такой простой язык программирования. Действительно, на нём легко начать, у него низкий порог первоначального входа. Но это вовсе не язык только лишь для новичков, такое отношение к нему порождает безответственный подход к разработке. Язык взял много хорошего от других, он не простой, со своими плюсами и минусами, очень красивыми местами и не самыми лучшими. И всё это требует освоения.
Можем сказать, что мы снова про скорость. Когда заходит разговор о тредах и Python, о скорости и Python, сразу на сцену выползает наш любимый и обожаемый GIL.
Ограничения GIL известны всем — в Python при попытке распаралеллить любую CPU-bound нагрузку с помощью тредов, разработчики неизбежно сталкиваются с тем, что в один момент у всегда будет работать только один поток. Тема абсолютно выдающаяся и имеющая за собой такой поток реминисценций, что про это даже немного неловко говорить, — но поговорить нам, всё-таки, в рамках статьи нужно.
Издалека проблема GIL — и сложная, и, как кажется, практически нерешаемая (мы все помним, что на этот счет сказали Гвидо, Дэвид Бизли; UPD: тут недавно вышла статья, говорят о nogil… но давайте не будем об этом).
В современных бэкендах и Python накал страстей вокруг GIL сильно стих — веб-сервисы очень часто по своей природе могут быть асинхронными, а для этого у нас есть множество чудесных фреймворков, вроде FastAPI, поэтому ограничения GIL нас не так сильно касаются. При этом горизонтально мы масштабируемся процессами, как в синхронных бэкендах, так и в асинхронных. У многих есть кубер — и там мы масштабируемся тоже процессами, только над ними стоит абстракция уровнем выше — pod.
Изрядно поношенный GIL
Некоторые разработчики спрашивают, зачем нам тогда треды?
В современном Python их используют для одной интересной штуки — на них можно делать wannabe-асинхронный код, при этом не делая асинхронный код, как ни странно. То есть можно написать на тредах что-то, что занимается интенсивной i/o-нагрузкой. И тогда внезапно все станет асинхронным за счет того, что GIL отпускается на i/o-операциях.
Это важное примечание, так как это сложный и неочевидный нюанс работы GIL — он описан в документации, но кто же её читает — шутка :). Но благодаря ему мы можем получить преимущество даже в синхронном коде, а также не блокировать петлю событий, когда у нас возникает потребность вызвать синхронное i/o в петле событий (вспомним про запись файлов, привет экзекьюторам).
Python — «неказистый язык для набрасывания прототипов на Django»
Частое мнение в интернете — Python годен только для быстрого, реактивного набрасывания прототипов на Django, а все остальное удел «серьезных языков» (тм). И это ещe одно, с моей точки зрения, не очень корректное суждение.
Конечно, на Django, на Python быстро набрасывают прототипы — я не буду отрицать очевидного. Но на языке делают не только это, описанное — лишь малая часть возможностей экосистемы Python. Однако быстро прототипирующие люди, использующие язык одним способом, почему-то взяли на себя прерогативу оценивать позиционирование языка по своей сфере. И с этим я не согласен.
В качестве одного из контраргументов можно привести наш выдающийся тулсет для написания тестов, который не мог возникнуть в языке для быстрого набрасывания прототипов за ненадобностью.
Pytest — это прекрасный фреймворк для написания тестов и яркий представитель этого тулсета. Он позволяет выстраивать очень сложные тестовые сценарии с инверсией зависимостей всего с помощью двух инструментов — fixtures и parametrize. С их помощью можно делать очень сложные тесты — подробно изучать производительность и бизнес-логику системы.
В тестировании, помимо Pytest, у нас есть Hypothesis — отличный фреймворк для fuzzy, property тестирования. Фреймворк настолько впечатляет, что недавно, на Python Language Summit 2021, стало известно, что его используют core developer’ы и с помощью него нашли ошибки в PEG парсере самого Python.
Использовать его просто, а результатом являются такие тесты, о которых я раньше только мечтал. В итоге из одного теста у нас получается целая последовательность, которая имеет различные статические проверки, динамические, а также случайно сгенерированные:
Для Python существует библиотека для мутационного тестирования mutmut. Если вы вдруг с ней не сталкивались — посмотрите, это очень интересный инструмент. С его помощью можно проверять ваши тесты через небольшие изменения в коде — я бы назвал это мета-тестированием.
Вообще, в Python есть огромное количество вспомогательных библиотек для тестирования — Faker, Factory boy, Mixer, Seed, куча расширений для Pytest — например, для параллелизации. Поэтому говорить, что Python можно использовать только для быстрого прототипирования на Django — немного некорректно.
Безопасность
Как-то раз нам написали комментарий, что за Java и C# стоят крупные компании, бизнес, а за Python только Гвидо и никакой ответственности нет. Видимо, это означало, что языком пользоваться страшно и от этого он абсолютно несерьезен.
Мне кажется, этот вопрос довольно сложный. Крупные проблемы языковой среды — не такой уж и частый сценарий. Но вряд ли при серьезных проблемах разработчики на Java или C# моментально получат их решение.
А ещё можно вспомнить, что современный софт пишется с использованием огромного количества Open Source библиотек, которые пишутся сторонними разработчиками, лежат в открытом доступе — и баги там случаются часто, а гарантий их исправления нет и быть не может. Тогда как серьезные проблемы Python, в случае их возникновения, точно будут исправлены. К тому же у Python «сжался» релизный график.
Поэтому проблемы у многих языков, как я считаю, общие, — и выделять энтерпрайз-языки отдельно, ставить их выше — не совсем правильно.
Популярность
Популярность языка программирования часто оценивают на результатах рейтингов. Поскольку вокруг них ходит огромное количество споров, я решил проанализировать почти все известные рейтинги по популярности языков.
У нас есть аналитика GitHub, здесь Python сразу за JavaScript Google-тренды довольно наглядно показывают, что Python очень долго рос все эти годы и умудрился своей неспешной змеиной «походкой» обогнать мощных конкурентов Рейтинг PYPL (некоторые говорят, что он не очень объективен) Любимый многими RedMonk. Кто-то считает его довольно объективным Менее известный рейтинг IEEE Spectrum, который агрегирует данные из 11 источников, включая (но не только) некоторые из описанных выше и ниже Stackoverflow говорит, что по популярности Python сейчас третий Вот и всем известный и бесконечно критикуемый TIOBE
Причин роста много, но кроме известных, для себя я предпочитаю выделять такую: одна из сильнейших черт Python в том, что он по пути вбирал в себя огромное количество разных парадигм и подходов, зачастую беря из них если не лучшие, то как минимум хорошие куски. Именно поэтому он умудряется быть таким универсальным и при этом довольно дружелюбным. Хм, дружелюбный сосед-питон? (шутка, предоставлена ЗАО «бумер-кринж»).
И о минусах
Что? Секундочку, ведь я только что активно поддерживал Python, а теперь начинаю перечислять минусы? Дело в том, что мне не хочется выглядеть как фанатик в розовых очках. Поэтому я просто назову уже не совсем типовые вещи, но тоже часто встречающиеся:
GIL всё ещё нас беспокоит. В итоге I/O-bound с небольшим количеством CPU-bound может привести к тому, что некоторые сигналы будут не доставлены.
У нас нет оптимизации хвостовой рекурсии (а нужна ли она?). Это большой топик.
Некоторые не любят пробелы… вспомним Whython. Я до сих пор не понимаю, в чем проблема — я везде код форматирую пробелами, а в Python они дают возможность избежать написания «лишних» скобок. Но не признать того, что есть недовольные, нельзя.
Lambda — есть разработчики, которые хотели бы видеть их как функции. Тогда как в Python они устроены в качестве выражений.
Python 2 и 3. Это неактуальный топик на текущий день, и Python 3 принес столько невероятных вещей, что о второй версии говорить нет желания. Но стоит признать — это было больно, и многие ещё помнят, насколько болезненно дался переход. Некоторых это отвращает от языка: подсознательно ты ждешь Python 3 vs 4.
Специфический подход к ООП.
Смешение парадигм даётся не всегда просто.
Я не буду сейчас пытаться разбираться ещё и в этих пунктах, но это всегда повод для отдельной дискуссии. Возможно — в комментариях.
Небольшие итоги
Я хочу сказать, что Python, на мой взгляд, надежен для большинства кейсов, с которыми мы сталкиваемся в бэкенд-разработке. С поправкой на хайлоад, конечно.
Python используется большинством авторитетных компаний, таких как Google и Яндекс. При этом популярность языка продолжает расти, а так же Гвидо недавно на Python Language Summit 2021 обещал, что с поддержкой Microsoft он сделает Python быстрее раз в пять, во многом с помощью jit. Может быть из конца списка языков в бенчмарках мы переместимся в середину, и уж там то точно заживем.
В Python фантастические веб-фреймворки. Можем вспомнить Django или FastAPI — это выдающиеся фреймворки, со своими плюсами и минусами. Современный Python можно брать для написания быстрых, хороших и серьезных бэкендов. В Python-среде много крутых разработчиков и приятных людей!
Python жутко популярен и продолжает расти. Потенциал его роста не исчерпан.
Для меня Python — язык для написания бэкенда номер один. Язык, с которого я начинаю любой бекенд в 2021 и только в каких-то исключительных ситуациях беру другие.
А ещё на Python очень приятно писать код — и этого совершенно не стоит стесняться.