Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 2

Вот некоторая информация о 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. Обычно он создает один огромный файл 2MB+, но если вы удалите то, что вы не используете, он может быть довольно маленьким. Выполнение этого означает, что вам нужно только вставить brython.js, py_VFS.js и ваш код на python, и никаких дополнительных запросов XHR не потребуется.

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

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

myList = []
if myList:    # False in CPython bcs it 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 (как новая встроенная -i n-версия virtualenv, которая использует меньше места для каждого проекта), чтобы настроить папку проекта python3.5 (просто введите: python3.5 -m venv foldername - обходной путь для ubuntu с пакетом вопросы за 3.5). Это делает 'foldername' с подпапкой bin среди других вещей.
  2. Установите пакет Python Transcrypt с помощью pip ('имя_фолдера /bin/pip install transcrypt'), который установит его в папку /lib/python3.5/site-packages/transcrypt.
  3. activate текущий терминал, если вы не хотите каждый раз вводить полный путь к 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 или просто использовать 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) Brython set_timeout заменяется javascripts setTimeout 5) Brython html-теги, такие как BR(), должны быть заменены обычными способами javascript, а также переделкой любых мест, которые вы использовали, <= dom синтаксис манипуляции. Либо добавьте разметку в виде простого текста как innerHTML, либо создайте элементы с использованием синтаксиса javascript, а затем присоедините их с использованием обычного синтаксиса DOM javascript. Я также заметил, что для флажков brython использует "if checkbox = 'checked':", но 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". Но это может быть связано с чем-то в Brython json.loads, который я заменил непосредственно на 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 я in dict:", не включив ее (строка cmd -i или __pragma__('iconv'), но вы можете избежать включения ее, просто используя ключ() член например:

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. И использование этого научило меня немного об оптимизации.

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

Ответ 3

Я использовал и взял на себя обязательство лепить так же, как 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 не реализован, потому что официально это аппаратная функция.

Ответ 4

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

Эта страница сравнивает трех кандидатов. Брайтон становится явным победителем.

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

Возможно, люди слишком поспешны?

Ответ 5

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

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

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

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

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

TODO: Я постараюсь дополнить свой ответ надежными бенчмарками.

Ответ 6

Здесь не упоминается ни 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#!topic/brython/20hAC9L3ayE

Ответ 7

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

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

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

Ответ 8

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

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

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