Jython, IronPython, RustPython и Brython: Python на чужих платформах
Четыре реализации для четырёх сред: Python на JVM, на .NET, на Rust и прямо в браузере. Зачем их переписывали, что они умеют сегодня и чем Brython отличается от Pyodide из песочницы.
Редакция Питоники
CPython, PyPy и MicroPython закрыли вопросы скорости и размера. Остались две редкие, но показательные причины существовать для реализаций: платформа и среда. Четыре проекта этого урока отвечают на четыре вопроса: как исполнить Python там, где правит Java; где правит .NET; как встроить язык в чужие программы на Rust; и как исполнять его прямо в браузере без установки чего-либо.
Зачем переписывать Python под чужую платформу
Ответ один для Jython и IronPython: мост к библиотекам. Программы на Java и .NET держат гигантские экосистемы классов, и реализация Python поверх платформы позволяет дотягиваться до них прямо из Python-кода: Jython видит Java-классы как свои, IronPython — объекты .NET. Это делает Python языком скриптов для целых платформ: конфигурация, автоматизация, расширение чужих приложений. Сам язык при этом не меняется — и переносимость обычного кода стоит на месте:
class Account:
def __init__(self, owner):
self.owner = owner
self.balance = 0
def deposit(self, amount):
self.balance = self.balance + amount
return self.balance
acc = Account('Анна')
acc.deposit(100)
print('после второго взноса:', acc.deposit(50))
print(acc.owner, '-', acc.balance)
после второго взноса: 150 Анна - 150
Этот класс поведёт себя одинаково на CPython, Jython и IronPython: классы, атрибуты, методы — часть языка. Различия начинаются на границе: то, что в Jython выглядит обычным объектом, может быть настоящим Java-классом, и у него появятся платформенные методы, которых нет у питон-объектов. Чистый Python-код без платформенных мостов переносится между реализациями: меняется среда, а не семантика языка.
Четыре реализации одним взглядом
| Реализация | Среда | Состояние | Зачем существует |
|---|---|---|---|
| Jython | JVM | Выпускается медленно, уровень Python 2 | Python-код поверх Java-классов |
| IronPython | .NET | Живая линия Python 3, совместимость отстаёт от CPython | Скрипты внутри .NET-приложений |
| RustPython | Встраивание, WASM | В разработке, совместимость неполная | Встраивать Python в Rust-проекты |
| Brython | Браузер | Активная разработка | Python-синтаксис вместо JavaScript над DOM |
Статусы разные, и на них стоит смотреть трезво. Jython десятилетиями живёт на уровне Python 2 — современный код с f-строками там не запустится. IronPython добрался до линии Python 3, но отставание от CPython — в релизы: новые конструкции языка появляются с задержкой. RustPython — молодой проект: значительная часть языка работает, но полная совместимость ещё впереди, зато его удобно встраивать в программы на Rust и собирать в WebAssembly. Brython живёт в браузере: он переводит Python-код в JavaScript прямо на странице, без установки интерпретатора.
Как код узнаёт среду
Каждая реализация честно называет себя через sys.implementation: Jython — java, IronPython — cli, у RustPython — rust. Тот же каркас из урока 16 с переносимым словарём имён:
import sys
NAMES = {
'cpython': 'эталонная реализация на C',
'pypy': 'PyPy: JIT на Python',
'java': 'Jython на JVM',
'cli': 'IronPython на .NET',
'rust': 'RustPython на Rust',
}
impl = sys.implementation.name
print('здесь работает:', NAMES.get(impl, 'другая реализация'))
здесь работает: эталонная реализация на C
В песочнице сработала запись для cpython; на настоящей Jython-машине словарь вернул бы значение про JVM. Метод get со значением по умолчанию — правильная манера для таких таблиц: неизвестная реализация не уронит код, а попадёт в запасную ветку. Brython в этот словарь тоже попадёт — он реализует sys.implementation со своим именем.
Отдельный вопрос — что из коллекций переезжает на платформы без потерь. Словари и сортировка — часть языка, и на любой из четырёх сред такой код работает одинаково:
stock = {'tool': 5, 'box': 2}
for name, count in sorted(stock.items()):
print(name, '-', count)
print('всего позиций:', len(stock))
box - 2 tool - 5 всего позиций: 2
Brython: браузер как среда
Brython — самый необычный из четырёх: вместо интерпретатора под платформу он работает прямо в браузере. Страница подключает Brython, тот читает Python-код из тега с типом text/python, транслирует его в JavaScript и выполняет. DOM при этом доступен через модуль browser — проверим, что на обычном Python его нет:
try:
from browser import document
print('browser доступен: мы внутри Brython')
except ImportError:
print('browser недоступен: обычный Python без DOM')
browser недоступен: обычный Python без DOM
В песочнице ответ тот же, что и для machine из урока 18: модуль из чужой среды честно не импортируется. На странице с подключённым Brython первая ветка открылась бы, и document стал бы живым DOM-объектом, с которым Python-код меняет содержимое страницы:
<script type='text/python'>
from browser import document
document <= 'Привет из Python'
</script>
Запись document <= текст — Brython-овская вставка содержимого в элемент: платформенные API приходят со своим синтаксисом. Это и есть цена моста: язык остаётся питоном, но граница со средой живёт по правилам среды.
Чем Brython отличается от Pyodide
На первый взгляд два способа исполнять Python в браузере — а на самом деле это противоположные подходы. Песочница этого сайта работает на Pyodide: это настоящий CPython, скомпилированный в WebAssembly — урок 16 показывал, что он честно отвечает cpython. Brython — не CPython: это отдельная реализация на JavaScript, и гарантии у неё другие:
| Свойство | Pyodide | Brython |
|---|---|---|
| Что это | CPython в WebAssembly | Реализация Python на JavaScript |
| Совместимость | Полная CPython-совместимость | Большая часть языка, свои ограничения |
| C-расширения | Работают: пакеты скомпилированы под WASM | Не поддерживаются |
| Доступ к DOM | Нет: это среда без браузерного DOM | Да, через модуль browser |
| Вес | Мегабайты: везёт настоящий интерпретатор | Легче: транслятор вместо интерпретатора |
Практический итог: для серьёзных вычислений и настоящих библиотек в браузере берут Pyodide — он несёт настоящий CPython и его пакеты; Brython выигрывает весом и прямотой к DOM — учебные страницы и простые веб-приложения на Python-синтаксисе. Для песочницы Питоники выбор очевиден: совместимость важнее, поэтому уроки компиляции исполняются на честном CPython.
Статус и выбор
- Jython — если поддерживаете наследие с Java и Python 2-уровнем: современный код на него не нацеливают;
- IronPython — если встраиваете скрипты в .NET-приложения: тот редкий случай, когда платформа важнее свежести языка;
- RustPython — следить и экспериментировать: встраивание в Rust-проекты и WASM-сборки;
- Brython — учебные страницы и лёгкие веб-приложения на Python-синтаксисе;
- настоящий Python в браузере — чаще Pyodide: полный CPython с пакетами.
import sys
report = [
'реализация: ' + sys.implementation.name,
'версия языка не ниже 3.6: ' + str(sys.version_info >= (3, 6)),
'байткод-машина: ' + str(hasattr(sys.implementation, 'cache_tag')),
]
for line in report:
print(line)
реализация: cpython версия языка не ниже 3.6: True байткод-машина: True
Три строки отчёта перенесутся на любую из четырёх реализаций без правок: имя вернётся своё, проверка версии отработает по-своему честно, а cache_tag есть у всех сред с байткод-кэшем. Это хороший тест переносимости: если отчёт о среде живёт — каркас программы переносим, различия будут только на платформенных границах.
Чистый Python-код без платформенных мостов переносится между реализациями: меняется среда, а не семантика языка. Jython и IronPython покупают мосты к Java и .NET ценой отставания, RustPython — встраиваемость ценой незавершённости, Brython — браузер ценой JavaScript-природы. Раздел о реализациях на этом закрыт, и впереди — финальный проект: собираем standalone-инструмент из исходника до проверенного архива.
Сначала предскажи ответ в голове — это главный навык программиста.
import sys
NAMES = {
'cpython': 'эталон',
'java': 'Jython',
'cli': 'IronPython',
}
print(NAMES.get(sys.implementation.name, 'неизвестно'))
try:
from browser import document
print('есть DOM')
except ImportError:
print('нет DOM')
class Point:
def __init__(self, x):
self.x = x
def double(self):
return self.x * 2
p = Point(21)
print(p.double())
1. Зачем существуют Jython и IronPython?
2. Какое имя возвращает sys.implementation.name на Jython?
3. На каком уровне языка находится современный Jython?
4. Что делает Brython со страницей?
5. Чем Pyodide отличается от Brython?
6. Заработает ли numpy через C API на RustPython?
7. Что означает hasattr(sys.implementation, 'cache_tag') == True?
Напишите функцию platform_label(), которая по имени реализации возвращает эталон для cpython и альтернатива для любого другого имени. Напечатайте имя текущей среды и её роль.
Что такое Jython и жив ли он?
Jython — реализация Python на JVM с прямым доступом к Java-классам. Он жив, но остался на уровне Python 2: для нового кода его не выбирают, только для поддержки старых систем на Java.
Чем IronPython отличается от CPython?
IronPython исполняет Python поверх .NET: его сила — прямой доступ к объектам .NET и встраивание скриптов в приложения на этой платформе. Языковая совместимость отстаёт от CPython на релизы, а C-расширения не работают.
Урок 16: реализации PythonМожно ли писать веб-страницы на Python через Brython?
Да: страница подключает Brython, и Python-код из тега text/python выполняется в браузере, меняя DOM через модуль browser. Для больших проектов чаще берут Pyodide — настоящий CPython в WebAssembly.
Что такое RustPython и готов ли он к работе?
Это встраиваемая реализация Python на Rust. Значительная часть языка уже работает, но полная совместимость ещё в разработке. Ценность — встраивание Python в Rust-проекты и сборки под WebAssembly.
Какой код переносится между всеми этими реализациями?
Чистый Python без платформенных мостов: классы, словари, сортировка, стандартные алгоритмы. Непереносимы C-расширения и опора на новейший синтаксис — альтернативы отстают от CPython по версиям.
Понравился урок? Сошлитесь на него
«Чистый Python-код без платформенных мостов переносится между реализациями: меняется среда, а не семантика языка.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Компиляция · Урок 16
Реализации Python: CPython и альтернативные среды
Python — это язык, а CPython — его главная реализация. Разбираем, кто ещё исполняет Python-код, как узнать свою среду через sys.implementation и что гарантировано любому коду на любой реализации.
Компиляция · Урок 17
PyPy: JIT-компилятор Python и когда он выигрывает
Тот же язык, другой движок: PyPy компилирует горячие участки прямо во время работы. Разбираем разогрев, ускорение в разы, совместимость с C-расширениями и случаи, когда CPython остаётся правильным выбором.
Компиляция · Урок 18
MicroPython: Python для микроконтроллеров ESP32 и RP2040
Python, который живёт на чипе за пару долларов: интерпретатор в сотни килобайт, модуль machine для пинов и стандартная библиотека, ужатая до сути. Разбираем отличия от CPython и стиль кода под маленькую память.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.