[Перевод] Brython: заменяем JavaScript на Python на фронтенде

Привет, Хабр!

К огромному удовлетворению нашей читательской аудитории, наша работа над обновлением книг по Python не прекращается. Но не прекращается и поиск в этом направлении — и сегодня мы хотели бы упомянуть Brython — Python для браузеров. Статья короткая, немного игривая и детективная, мы постарались сохранить авторский стиль.

В этой статье дается краткое введение в работу с Brython, реализацией Python для разработки на фронтенде (в браузере).

Весь проект выложен здесь.

Введение


Завидуя успеху программистов JavaScript, питонисты-заговорщики тайно встретились, чтобы обсудить будущее Python в этом апокалиптическом мире. Повсюду JavaScript, отжирающий поляну у Python. Вооружившись Node.js, язык JavaScript вторгся на территорию Python, и тот утратил свою доминирующую роль всеми любимого серверного языка, где ранее соперничал с Ruby (помните те времена?). Тогда пришло время сделать вылазку в самое сердце территории JavaScript: в браузер.

Не забывайте вашу историю (и помните о будущем)


Эта дилемма волновала не только вышеупомянутых заговорщиков. Был еще один рыцарь плаща и кинжала, автор Transcrypt. Он решил написать компилятор для Python, компилирующий код прямо в JavaScript Как хороший отравитель, он не оставлял после себя и следа Python. Выглядело это многообещающе.

Другие предпочитали воспользоваться уроками истории. Просто иммигрировать всей семьей. По крайней мере, именно так мыслили создатели Pyodide. Они собирались создать на стороне JavaScript анклав с полноценным интерпретатором Python, который мог бы выполнять код на Python. Соответственно, там можно было гонять любой код Python, в том числе, большую часть его стека для data science, где есть привязки к языку C (например, Numpy, Pandas).

Это также выглядит очень многообещающе. Но первичные ленивые тесты, проведенные автором Pyodide, показали, что поначалу страница грузилась немного медленно.

Тогда заговорщики поступили именно в духе хороших заговорщиков: создали другой компилятор для преобразования Python в JavaScript, но на этот раз выполнять компиляцию в JavaScript при загрузке страницы (а не как Transcrypt, компилирующий код в JavaScript заранее). Так сформировалось Братство Brython. Одна змея, чтоб править ими всеми.

Hello World


Давайте напишем традиционный «Hello World»

А вот и десант Brython (это я о компиляторе).


Активируем его при загрузке страницы

...











В теге body, показанном выше, мы пишем код на Brython:


Просто добавляем Hello World в элемент document. Хм. Очень легко.

В полном виде — ниже.




    
    






В таком случае на страницу будет просто выведено приветствие «Hello World».

Калькулятор


Давайте напишем калькулятор на Brython. Весь его код выложен здесь.

3ju7xmnpfev_bnaosovnxqahzm8.png

Да, вы догадались, нам понадобится таблица. Давайте ее сделаем.

from browser import document, html
calc = html.TABLE()

Добавим только первый ряд. То есть отобразим поле для чисел (назовем его result) и клавишу C.

calc <= html.TR(html.TH(html.DIV("0", id="result"), colspan=3) +
                html.TD("C"))

Да, я тоже не слишком уверен в этом синтаксисе с <=. Но, посудите сами, такая классная библиотека, так что я и на него согласен.

Теперь добавим клавиатуру

lines = ["789/", "456*", "123-", "0.=+"]
calc <= (html.TR(html.TD(x) for x in line) for line in lines)

Наконец, добавим calc в document.

document <= calc

Итак, пока все хорошо. Как же нам добиться, чтобы все это работало? Сначала нужно захватить ссылку на элемент result, чтобы управлять им, когда будут нажиматься клавиши.

result = document["result"] # прямой доступ к элементу по его id

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

def action(event):
    """обрабатывает событие "click" при нажатии на кнопку калькулятора."""
    # Элементу, нажатому пользователем, соответствует атрибут "target" 
    # объекта event 
    element = event.target
    # Текст, выводимый на кнопке, записывается в атрибуте "text" элемента
    value = element.text
    if value not in "=C":
        # обновляем поле с результатом
        if result.text in ["0", "error"]:
            result.text = value
        else:
            result.text = result.text + value
    elif value == "C":
        # сброс
        result.text = "0"
    elif value == "=":
        # выполняем формулу в поле с результатом
        try:
            result.text = eval(result.text)
        except:
            result.text = "error"

Наконец, связываем вышеописанный обработчик событий с событием click на всех кнопках.

for button in document.select("td"):
    button.bind("click", action)

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

© Habrahabr.ru