Python в браузере: как выбрать между Brython, PyPy.js, Skulpt и Transcrypt?

Я очень рад видеть, что теперь можно кодировать Python в браузере. Вот основные кандидаты (пожалуйста, добавьте все, что я мог упустить из виду):

Но как выбрать между ними? Единственное очевидное отличие, которое я вижу, состоит в том, что Skulpt основан на Python 2, тогда как Brython основан на Python 3.

Обратите внимание: это не запрос рекомендаций или мнений. Я ищу объективные факты, которые позволили бы сделать обоснованный выбор.

8 ответов

Решение

Это также может быть полезно: http://stromberg.dnsalias.org/~strombrg/pybrowser/python-browser.html

Он сравнивает несколько технологий Python-in-the-browser.

Вот некоторая информация о Brython против Transcrypt (июль 2016 года, так как OP был добавлен в качестве опции по этому вопросу OP), который был получен после запуска проекта с Brython несколько месяцев назад и перехода к Transcrypt (завершено перемещение на прошлой неделе). Мне нравятся Brython и Transcrypt, и я вижу их применение.

Для новичков в этом Brython и Transcrypt "переносят" ввод Python в javascript (Правка: может быть, лучше рассматривать Brython как "реализацию Python для браузера", потому что он не создает автономный javascript). Оба требуют синтаксиса Python 3. Brython включает в себя значительное количество стандартных библиотек Python и несколько своих собственных для работы с веб-технологиями, тогда как Transcrypt по большей части избегает этого и предлагает вместо этого использовать библиотеки Javascript.

Brython ( Github) может сделать преобразование в браузере. Таким образом, вы пишете на python, а движок brython.js преобразует его в javascript на лету, когда страница загружается. Это действительно удобно и намного быстрее, чем вы думаете. Однако, движок brython.js, который вам нужно включить в свои страницы, составляет около 500 Кб. Кроме того, существует проблема импорта стандартных библиотек, которые Brython обрабатывает путем извлечения отдельных файлов.js с запросами XHR. Некоторые библиотеки уже скомпилированы в brython.js, поэтому не каждый импорт будет извлекать новые файлы, но если вы используете много импортов, все может стать медленным. Однако есть способы обойти это. Что я сделал, так это проверил вкладку сети в инструментах разработчика браузера, чтобы увидеть, какие файлы извлекались при загрузке страницы, затем удалил все файлы, которые мой проект не использовал, в копии папки Brython src, и запустил Скрипт, включенный в Brython (я думаю, что он находится в Brython/www/scripts/make_VFS.py), который компилирует все доступные библиотеки в один файл с именем py_VFS.js, на который вам также нужно сослаться из вашего html. Обычно он создает один огромный файл размером более 2 МБ, но если вы удалите то, что не используете, он может оказаться совсем крошечным. Выполнение этого означает, что вам нужно только вставить brython.js, py_VFS.js и ваш код на python, и никаких дополнительных запросов XHR не потребуется.

Transcrypt ( Github), с другой стороны, распространяется как пакет python 3, который вы можете использовать вручную или подключить к своей цепочке инструментов, чтобы заранее скомпилировать python в javascript. Таким образом, в Transcrypt вы пишете на python, запускаете transcrypt против python, и он выдает JavaScript, на который вы можете ссылаться в своем проекте. Он больше похож на традиционный компилятор и в том, что он предлагает некоторый контроль над выводом. Например, вы можете выбрать компиляцию в ES6 или ES5 или попросить его вывести исходные карты (что во время отладки позволяет браузеру перенаправить вас непосредственно к соответствующему коду Python, а не к сгенерированному коду JavaScript). Вывод JavaScript в Transcrypt довольно лаконичен (или иначе говоря, это красиво и лаконично). В моем случае 150 КБ Python преобразуется в 165 КБ незавершенного JavaScript ES5. Для сравнения, Brython-версия моего проекта использовала около 800Kb после конвертации.

Однако, чтобы получить преимущества краткости Transcrypts, требуется немного прочитать документы (на самом деле, немного). Например, в Transcrypt "правдивость" Python для структур данных, таких как dict, set и list, не включена по умолчанию, а глобальное включение не рекомендуется из-за потенциальных проблем производительности, связанных с проверкой типов. Для ясности: в CPython пустой dict, set или list имеет значение истины False, тогда как в Javascript это считается "истиной". Пример:

myList = []
if myList:    # False in CPython bcs it's empty, true in javascript bcs it exists
    # do some things.

Есть как минимум три способа решения этой проблемы:

  • Используйте флаг -t при преобразовании python в javascript, например: $ transcrypt -t python.py (не рекомендуется, но, вероятно, это не проблема, если вы не проверяете правильность много раз во внутренних циклах кода, чувствительного к производительности..)
  • использование __pragma__(tconv) или же __pragma__(notconv) в вашем коде, чтобы сказать компилятору transcrypt включить автоматическое преобразование в Python-подобные значения истинности локально.
  • Вместо того, чтобы проверять значение истинности, полностью избегайте проблемы, просто проверяя len(myList) > 0... Может быть, это подойдет для большинства ситуаций, подойдет для моего легкого использования.

Итак, мой проект становился больше, и я хотел предварительно скомпилировать для увеличения производительности, но мне было трудно это сделать с помощью Brython (хотя это технически возможно, простой способ - использовать онлайн-редактор и нажать кнопку javascript, чтобы увидеть выход). Я сделал это и связался с сгенерированным javascript из project.html, но по какой-то причине он не работал. Кроме того, мне трудно понять сообщения об ошибках от Brython, поэтому я не знал, с чего начать после сбоя этого шага. Кроме того, большой размер выводимого кода и размер движка brython начинали меня беспокоить. Поэтому я решил поближе познакомиться с Transcrypt, который на первый взгляд казался более высокой оценкой, потому что я предпочитаю тупые инструкции, которые говорят мне, как начать работу немедленно (они были добавлены).

Главное, что нужно было настроить после установки Python3.5, это: 1) использовать venv (это как новая встроенная версия virtualenv, которая использует меньше места для каждого проекта) для настройки папки проекта python3.5 (просто введите: python3.5 -m venv foldername - обходной путь для Ubuntu с проблемами пакета для 3.5). Это делает 'foldername' с подпапкой bin среди других вещей. 2) установить пакет Python Transcrypt с помощью pip ('foldername/bin/pip install transcrypt'), который установит его в папку foldername/lib/python3.5/site-packages/transcrypt. 3) "активировать" текущий терминал, если вы не хотите каждый раз вводить полный путь к foldername/bin/python3.5. Активируйте, набрав: 'имя источника /bin/activ' 4) начните писать код и компилировать его в javascript для тестирования. Компилировать из папки, в которой вы пишете свой код. Например, я использовал foldername/www/project. Поэтому CD в эту папку и запустите: 'transcrypt -b your_python_script.py'. Это помещает вывод в подпапку с именем __javascript__, Затем вы можете сделать ссылку на выведенный JavaScript из вашего HTML.

Основные проблемы, возникающие в

У меня довольно простые потребности, поэтому ваш пробег может отличаться.

  • Вам необходимо заменить стандартные библиотеки brython или python на библиотеки javascript. Так, например, "импорт json" предоставляется Brython, но в Transcrypt вы можете использовать javascript lib или просто использовать JSON.parse / JSON.stringify непосредственно в вашем коде Python. Чтобы включить минимизированную версию библиотеки javascript непосредственно в код Python, используйте этот формат (обратите внимание на тройные кавычки):

    __pragma__ ('js', '{}', ''' // javascript code ''')

  • Html-функции Brython, очевидно, не работают с Transcrypt. Просто используйте обычные способы JavaScript. Примеры: 1) в Brython вы могли ссылаться на определенный тег HTML, используя 'document['id']', но с Transcrypt вы использовали бы 'document.getElementById('id') (то же самое, что вы делаете это из JavaScript). 2) Вы не можете удалить узел с 'del nodeName' (bcs, это функция brython). Используйте что-то вроде 'node.parentNode.removeChild(node)'. 3) заменить все функции DOM в brython альтернативами javascript. например, имя_класса = имя_класса; text = textContent; html = innerHTML; parent = parentNode; children = childNodes и т. д. Я думаю, если вам нужно что-то, что содержит альтернативы, требуемые некоторыми старыми браузерами, тогда для этого есть библиотеки javascript. 4) set_timeout Brython заменяется javascripts setTimeout 5) html-теги Brython, такие как BR(), необходимо заменять обычными способами javascript, а также повторять любые места, которые вы использовали, это синтаксис манипуляции <= dom. Либо добавьте разметку в виде простого текста как innerHTML, либо создайте элементы с использованием синтаксиса javascript, а затем присоедините их с использованием обычного синтаксиса DOM javascript. Я также заметил, что для флажков brython использует "if checkbox = 'флажок":"но Transcrypt доволен"if checkbox:"..

  • Я закончил перенос 2700-строчного проекта за последнюю неделю, когда у Transcrypt не было поддержки нескольких незначительных вещей (хотя их было достаточно легко заменить наполнителями), это были 1) str.lower, str.split (str.split присутствует, но, похоже, это расщепление javascript, которое работает не так, как версия Python, на поведение которой я опирался), 2) round (теперь это поддерживается в версии dev) и 3) isinstance didn не работает на str, int и float, только на dict, list и set. 4) Еще одно отличие от Brython, которое я заметил, заключается в том, что если я добавляю в JSON представление dict, мне нужно сделать это, используя "myDict = dict (data)", тогда как brython был доволен "myDict = data". Но это может быть связано с чем-то в json.loads Brython, который я заменил непосредственно на JSON.parse. 5) Также без специально включенной перегрузки оператора Transcrypts (с помощью параметра -o для глобального или __pragma__('opov') для локального), вы не можете делать такие вещи, как операции над множествами, используя перегруженный формат, но должны использовать соответствующие функции. Например

    a = set([1, 2, 3])
    b = set([3, 4, 5])
    a.difference(b)             # is used instead of a - b
    a.union(b)                  # used instead of a | b
    a.intersection(b)           # used instead of a & b
    a.symmetric_difference(b)   # used instead of a ^ b
    

6) Кроме того, вы не можете итерировать по умолчанию, используя 'for i in dict:', не включив его (строка cmd -i или __pragma__('iconv'), но вы можете избежать необходимости включать его, просто используя элемент keys(), например:

for key, value in dict.items():
    # do things for each key and value..

Чтобы подвести итог

  • Мне нравится Brython, потому что с ним легко начать и протестировать свой код (просто F5). Это ближе к настоящему питону, потому что там есть большая часть стандартной библиотеки. Мне не нравится включать в браузер механизм транспиляции (Edit: или можно рассматривать его как виртуальную машину Python) и большой размер выводимого JavaScript. Если бы мне пришлось что-то делать заново (но все еще используя Brython), я бы использовал методы javascript для манипулирования DOM из brython (что вы можете сделать) вместо того, чтобы слишком полагаться на методы brython, потому что это трата времени на перемещение в другой транспортер, когда мои потребности изменились.

  • Мне нравится Transcrypt, потому что выводимый javascript действительно "скудный и подлый", и потому что единственное, что вы загружаете на стороне браузера, это ваш сгенерированный код javascript, который по размеру похож на ваш код на python. Кроме того, потому что он поддерживает исходные карты и потому, что он дает мне контроль над выводимым JavaScript. И использование этого научило меня немного об оптимизации.

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

Запуск Python в браузере - действительно хорошая и актуальная (по состоянию на 2019 год) статья, в которой сравниваются Brython, Skulpt, PyPy.js, Transcrypt, Pyodide, Batavia. Я очень рекомендую это прочитать.

Хорошее резюме можно увидеть на следующих картинках.

Я использовал и взял на себя обязательство лепить, а также pypyjs. И они все три очень разные, что любое сравнение является спорным, если вы спросите меня.

Это зависит от того, что вы ищете, что будет иметь больше смысла.

PyPyJS

pypyjs огромен, это 12-мегабайтный файл javascript, который содержит всю виртуальную машину pypy. Так что если вы хотите завершенности реализации Python, это ваш ребенок. У него есть мост javascript, который работает действительно хорошо, но он не подходит для написания кода вашего сайта javascript на python. Это однако позволит вам import compiler,

Он построен с использованием emscripten и работает быстрее, чем CPython, при выполнении теста pystone.

Я кратко рассказал о pypyjs, вот слайды.

Skulpt

Это обучающий инструмент (или со временем он превратился в него), он компилирует ваш python в конечный автомат, очень близко эмулирующий компилятор cpython. По своей сути это собственноручная реализация компилятора python в javascript. Это позволяет выполнять асинхронное выполнение, которое позволяет вам:

while (True):
    print "hi"

Без блокировки браузера.

Skulpt - единственный, кто поддерживает асинхронные продолжения, он позволяет вам приостанавливать выполнение python, пока он разрешает некоторые асинхронные события. Заставить эту работу:

from time import sleep
sleep(1)

Skulpt работает примерно на одной десятой скорости CPython при сравнении pystone.

бритт

Я знаю меньше всего об этом, может быть, @ olemis-lang может расширить этот. Но рядом с очевидной разницей, что Brython - это py3, а остальные - py2. Brython также является транспортером.

Brython не запускает тест Pystone, потому что time.clock не реализован, потому что официально это аппаратная функция.

https://brythonista.wordpress.com/2015/03/28/comparing-the-speed-of-cpython-brython-skulpt-and-pypy-js/

На этой странице показаны три кандидата. Brython становится явным победителем.

Несмотря на "помощь", объясняющую, что SO не подходит для такого рода вопросов, похоже, что в этом случае возможен краткий ответ.

Может быть, люди слишком торопятся?

Прежде всего, я коммитер Brython. Тем не менее я постараюсь быть максимально беспристрастным для объективной оценки.

В прошлый раз, когда я использовал его, Skulpt не поддерживал такие функции, как выражения генератора. Brython и PyPy.js делают это, так что на уровне возможностей IMHO последние превосходят.

Brython (в настоящее время) все еще находится в стадии разработки. Некоторые модули не могут быть импортированы (например, xml.ElementTree). Тем не менее, эта ситуация начинает меняться, поскольку мы работаем над тем, чтобы запустить весь набор тестов CPython, несмотря на достижение полной совместимости со стандартами (по крайней мере, когда это имеет смысл).

Brython также поддерживает.vfs.js для ускорения импорта модулей.

PyPy.js имеет ряд характеристик, которые прямо вытекают из того факта, что он работает на PyPy (JIT-компиляция, хорошо протестирована, ...), но я не уверен, подходит ли он для работы в браузере. Это может измениться по мере развития проекта.

ТОДО: Я постараюсь дополнить мой ответ надежными контрольными показателями.

Здесь не упоминается ни RapydScript, ни RapydScript-NG. Они производят очень эффективный код JavaScript, который используется в GlowScript VPython (glowscript.org). Раньше я использовал оригинальный RapydScript Алекса Цепкова ( https://github.com/atsepkov/RapydScript), но недавно переключился на RapydScript-NG от Kovid Goyal ( https://github.com/kovidgoyal/rapydscript-ng). Недавно я запустил тестирование pystone для CPython, RapydScript и Brython, и вы можете увидеть результаты здесь:

https://groups.google.com/forum/?fromgroups&hl=en

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

Я только что попробовал и, хотя это интересная концепция, она все еще находится на ранних стадиях, так как документации мало.

В конце концов, это будет зависеть от того, что вы пытаетесь сделать. После того, как я посмотрел, я выбрал Transcrypt, потому что он был более прагматичным и более производительным, а также недавно выпущенным / поддерживаемым.

Это обновленная конференция, которая сравнивает все доступные на рынке варианты прямо сейчас:

https://www.youtube.com/watch?v=2XSeNQyPlTY

Докладчик - Рассел Кит-Маги, известный разработчик в этой области.

Другие вопросы по тегам