Python no navegador: como escolher entre Brython, PyPy.js, Skulpt e Transcrypt?

91

Estou muito animado em ver que agora é possível codificar Python no navegador. Estes são os principais candidatos (por favor, adicione qualquer um que eu tenha esquecido):

Mas como escolher entre eles? A única diferença óbvia que posso ver é que Skulpt é baseado em Python 2, enquanto Brython é baseado em Python 3.

Observação: este não é um pedido de recomendações ou opiniões. Estou buscando fatos objetivos que informariam uma escolha educada.

P i
fonte
6
Pedir-nos para recomendar a melhor biblioteca para algo é um dos casos para os quais a ajuda explica explicitamente que StackOverflow não é bom. É uma ótima pergunta, não apenas para o formato deste site; você provavelmente quer algo baseado em discussão, como uma lista de discussão ou fórum.
abarnert de
2
Transcrypt ( transcrypt.org ) compila a partir de um grande subconjunto de python3.5 inc. herança múltipla, gera código rápido (chamada memoizing), pequeno e legível, suporta mapas de origem multinível e pode usar qualquer biblioteca JS sem adaptação. Disclaimer: Eu escrevi.
Jacques de Hooge
1
Olá, fzzylogic, adicionei a tag, então as pessoas agora podem fazer perguntas sobre o uso dela. Substituída a tag JS por ela, porque é a menos provável para pesquisar se você preferir usar Python no navegador.
Jacques de Hooge
1
Eu escrevi uma espécie de tutorial para Transcrypt para iniciantes. Você pode vê-lo em github.com/bunkahle/Transcrypt-Examples/blob/master/alerts/… e github.com/bunkahle/Transcrypt-Examples/blob/master/cookies/…
bunkus
1
Resposta excluída por dstromberg com 27 votos positivos tem um bom link de comparação: stromberg.dnsalias.org/~strombrg/pybrowser/python-browser.html
Cees Timmerman

Respostas:

30

Executar Python no navegador é um artigo muito bom e atualizado (a partir de 2019) que compara Brython, Skulpt, PyPy.js, Transcrypt, Pyodide, Batavia . Eu recomendo a leitura.

Um bom resumo pode ser visto nas fotos a seguir.

insira a descrição da imagem aqui

insira a descrição da imagem aqui

laike9m
fonte
62

Aqui estão algumas informações sobre Brython vs Transcrypt (julho de 2016, uma vez que Transcrypt foi adicionado como uma opção nesta questão pelo OP), recolhidas iniciando um projeto com Brython alguns meses atrás e movendo para Transcrypt (mudança concluída na semana passada). Eu gosto de Brython e Transcrypt e posso ver os usos de ambos.

Para as pessoas que são novas nisso, Brython e Transcrypt ambos 'transpilar' a entrada python para javascript (Editar: talvez seja melhor ver Brython como uma 'uma implementação Python para o navegador' porque não produz javascript autônomo). Ambos requerem sintaxe Python 3. Brython inclui um número substancial de bibliotecas padrão Python e algumas das suas próprias para lidar com coisas relacionadas à web, enquanto o Transcrypt evita isso na maior parte e sugere o uso de bibliotecas Javascript.

Brython ( Github) pode fazer a conversão no navegador. Então, você escreve em python e o mecanismo brython.js o converte para javascript na hora quando a página é carregada. Isso é muito conveniente e muito mais rápido do que você imagina. No entanto, o mecanismo brython.js que você precisa incluir em suas páginas tem cerca de 500 KB. Além disso, há a questão da importação de bibliotecas padrão, que Brython lida buscando arquivos .js separados com solicitações XHR. Algumas libs já estão compiladas em brython.js, então nem toda importação irá puxar novos arquivos, mas se você usar muitas importações, as coisas podem ficar lentas. No entanto, existem maneiras de contornar isso. O que fiz foi verificar a guia de rede nas ferramentas de desenvolvimento do navegador para ver quais arquivos estavam sendo puxados quando a página foi carregada e, em seguida, excluir todos os arquivos que meu projeto não estava usando em uma cópia da pasta Brython src, e execute o script incluído no Brython (acho que está em Brython / www / scripts / make_VFS.py) que compila todas as libs disponíveis em um arquivo chamado py_VFS.js que você também precisa vincular a partir do seu html. Normalmente, ele formará um arquivo enorme de 2 MB +, mas se você excluir as coisas que não está usando, pode ser bem pequeno. Fazendo dessa maneira, você só precisa obter brython.js, py_VFS.js e seu código Python, e nenhuma solicitação XHR adicional será necessária.

Transcrypt ( Github ), por outro lado, é distribuído como um pacote python 3que você pode usar manualmente ou conectar em seu conjunto de ferramentas para compilar python para javascript com antecedência. Assim, com o Transcrypt, você escreve em python, executa o transcrypt no python e ele emite javascript para o qual você pode criar um link em seu projeto. É mais parecido com um compilador tradicional também porque oferece algum controle sobre a saída. Por exemplo, você pode escolher compilar para ES6 ou ES5, ou pedir para gerar mapas de origem (que durante a depuração permite que o navegador o leve diretamente para o código python correspondente, em vez do código javascript gerado.) A saída javascript do Transcrypt é muito concisa ( ou dito de outra forma, é bonito e conciso). No meu caso, 150kB de python são convertidos em 165kB de javascript ES5 não minimizado. A título de comparação, a versão Brython do meu projeto usou cerca de 800Kb após a conversão.

No entanto, para obter os benefícios da concisão do Transcrypts, é necessário ler os documentos um pouco (na verdade, apenas um pouco). Por exemplo, com o Transcrypt, a 'veracidade' do Python para estruturas de dados como dict, set e list não está habilitada por padrão e a habilitação global é desencorajada devido a possíveis problemas de desempenho relacionados à verificação de tipos. Para maior clareza: no CPython, um dicionário vazio, conjunto ou lista tem valor verdade False, enquanto em Javascript é considerado 'verdadeiro'. Exemplo:

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

Existem pelo menos três maneiras de resolver isso:

  • Use a sinalização -t ao converter python em javascript, por exemplo: $ transcrypt -t python.py (não recomendado, mas provavelmente não é um problema, a menos que você verifique a veracidade muitas vezes em loops internos de código sensível ao desempenho.)
  • Use __pragma__(tconv)ou __pragma__(notconv)em seu código para dizer ao compilador transcrypt para ativar a conversão automática para valores verdade do tipo python localmente.
  • Em vez de verificar o valor verdade, evite o problema completamente apenas verificando len (myList)> 0 ... Talvez isso seja adequado para a maioria das situações, faz o trabalho para meu uso de luz.

Certo, então meu projeto estava ficando maior e eu queria pré-compilar para um ganho de desempenho, mas achei difícil fazer isso com Brython (embora seja tecnicamente possível, uma maneira fácil de usar o editor online e clicar no botão javascript para ver a saída). Eu fiz isso e vinculei ao javascript gerado em project.html, mas não funcionou por algum motivo. Além disso, acho difícil entender as mensagens de erro de Brython, então não sabia por onde começar depois que essa etapa falhou. Além disso, o grande tamanho do código gerado e o tamanho do mecanismo brython estavam começando a me incomodar. Então decidi dar uma olhada mais de perto no Transcrypt, que a princípio parecia ter um grau mais alto porque eu prefiro instruções simplificadas que me dizem como começar imediatamente (elas já foram adicionadas).

A principal coisa para configurá-lo após a instalação do Python3.5 foi:

  1. Use o venv (é como uma nova versão integrada do virtualenv que usa menos espaço para cada projeto) para configurar uma pasta de projeto python3.5 (basta digitar: python3.5 -m venv foldername - solução alternativa para ubuntu com problemas de pacote para 3.5 ) Isso torna 'foldername' com uma subpasta bin entre outras coisas.
  2. Instale o pacote Transcrypt python com pip ('foldername / bin / pip install transcrypt'), que o instala em foldername / lib / python3.5 / site-packages / transcrypt.
  3. activateo terminal atual se você não quiser ter que digitar o caminho completo para nome da pasta / bin / python3.5 todas as vezes. Ative digitando: 'nome da pasta de origem / bin / ativar'
  4. Comece escrevendo o código e compilando-o em javascript para teste. Compile de dentro da pasta em que você escreveu seu código. Por exemplo, usei foldername / www / project. Então coloque o CD nessa pasta e execute: 'transcrypt -b your_python_script.py'. Isso coloca a saída em uma subpasta chamada __javascript__. Você pode então criar um link para o javascript gerado no seu html.

Principais problemas em andamento

Tenho necessidades bastante simples, então sua milhagem pode variar.

  • Você precisa substituir as bibliotecas padrão do brython ou python por bibliotecas javascript. Portanto, por exemplo, 'import json' é fornecido por Brython, mas em Transcrypt você pode usar uma lib javascript ou apenas usar JSON.parse / JSON.stringify diretamente em seu código Python. Para incluir uma versão reduzida de uma biblioteca javascript diretamente em seu código python, use este formato (observe as aspas triplas):

    __pragma__ ('js', '{}', '''
    // javascript code
    ''')
    
  • As funções específicas de html de Brython não funcionam com Transcrypt obviamente. Basta usar as formas normais de javascript. Exemplos: 1) em Brython, você pode ter se referido a uma tag HTML específica usando 'document [' id ']', mas com Transcrypt você usaria 'document.getElementById (' id ') (que é a mesma maneira que você faz de javascript). 2) Você não pode excluir um nó com 'del nodeName' (bcs que é uma função brython). Use algo como 'node.parentNode.removeChild (node)'. 3) substituir todas as funções DOM do brython pelas alternativas javascript. por exemplo, class_name = className; text = textContent; html = innerHTML; parent = parentNode; children = childNodes etc. Acho que se você precisa de algo que contenha alternativas exigidas por alguns navegadores mais antigos, existem bibliotecas javascript para isso. 4) O set_timeout de Brython é substituído por javascripts setTimeout 5) As tags html de Brython, como BR (), precisam ser substituídas usando as formas normais de javascript, bem como refazer quaisquer lugares que você usou em sua <= sintaxe de manipulação de dom. Injete a marcação de texto simples como innerHTML ou crie os elementos usando a sintaxe javascript e, em seguida, anexe-os usando a sintaxe javascript DOM normal. Também percebi que para as caixas de seleção o brython usa "if checkbox = 'checks':" mas a Transcrypt está satisfeita com "if checkbox:" .. Injete a marcação de texto simples como innerHTML ou crie os elementos usando a sintaxe javascript e, em seguida, anexe-os usando a sintaxe javascript DOM normal. Também percebi que para as caixas de seleção o brython usa "if checkbox = 'checks':" mas a Transcrypt está satisfeita com "if checkbox:" .. Injete a marcação de texto simples como innerHTML ou crie os elementos usando a sintaxe javascript e, em seguida, anexe-os usando a sintaxe javascript DOM normal. Também percebi que para as caixas de seleção o brython usa "if checkbox = 'checks':" mas a Transcrypt está satisfeita com "if checkbox:" ..

  • Terminei de mover um projeto de 2700 linhas na semana passada, momento em que o Transcrypt não tinha suporte para algumas coisas menores (embora fossem fáceis de substituir por enchimentos), que eram 1) str.lower, str.split (str. a divisão está presente, mas parece ser a divisão do javascript, que funciona de maneira diferente da versão python, cujo comportamento eu estava contando), 2) round (parece ser compatível na versão dev agora) e 3) isinstance didn 't trabalhar em str, int e float, apenas em dict, list e set. 4) Outra diferença de Brython que notei é que se eu puxar uma representação JSON de um dicionário, preciso fazer isso usando 'myDict = dict (data)', enquanto o brython fica feliz com 'myDict = data'. Mas isso pode estar relacionado a algo em json.loads de Brython, que substituí diretamente por JSON.parse.__pragma__('opov')para local), você não pode fazer coisas como definir operações usando o formato sobrecarregado, mas precisa usar as funções correspondentes. Por exemplo

    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) Além disso, você não pode iterar dicts por padrão usando 'for i in dict:', sem habilitar isso (cmd line -i ou __pragma__('iconv'), mas você pode evitar ter que habilitá-lo usando apenas o membro keys (), por exemplo:

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

Para resumir

  • Eu gosto do Brython porque é fácil de começar e testar seu código (apenas F5). É mais próximo do verdadeiro python porque a maior parte da biblioteca padrão está lá. Não gosto de ter que incluir o mecanismo de transpilação (Editar: Ou alguém pode vê-lo como uma VM python) no navegador e o grande tamanho de javascript de saída. Se eu tivesse que refazer as coisas (mas ainda usando Brython), eu teria usado métodos javascript para manipular o DOM do brython (o que você pode fazer ..), em vez de depender tanto dos métodos do brython porque isso é perda de tempo em para outro transpiler quando minhas necessidades mudassem.

  • Eu gosto de Transcrypt porque o javascript gerado é realmente 'enxuto' e porque a única coisa que você carrega do lado do navegador é o código javascript gerado, que é semelhante em tamanho ao seu código python. Também porque ele oferece suporte a mapas de fontes e porque me dá uma medida de controle sobre o javascript enviado. E usá-lo me ensinou um pouco sobre otimização.

Espero que ajude alguém a ver o que pode ser bom para seu projeto específico.

fzilógico
fonte
1
Tem certeza que Brython é um transpiler? Tenho certeza de que implementa um interpretador Python em JavaScript. Se fosse um transpiler, você não precisaria empacotá-lo com seu aplicativo.
Carl Smith
@Carl Smith Ponto interessante, não tinha pensado nisso assim. Brython converte o código python em javascript, mas como o javascript não tem um bytecode padrão, talvez seja possível visualizar o javascript gerado como 'bytecode' para o mecanismo Brython.
fzzylogic de
1
Você me entendeu mal. Eu não acho que Brython transpila Python para JavaScript. Ele apenas implementa um interpretador Python em JS, em vez de C. De acordo com seu README do GitHub "Brython (Browser Python) é uma implementação do Python 3 rodando no navegador, com uma interface para os elementos e eventos DOM".
Carl Smith
4
@jsbueno Atualmente disponíveis estão seed, randint, choice e random, que servem apenas como ponto de partida. Na verdade, esperamos que alguém o pegue e conclua, o mesmo que foi feito para re, que estava no topo de nossa lista. Não deve ser tão difícil. A quantidade de bibliotecas aumentou, mas as contribuições são muito bem-vindas. Enquanto a ênfase permanecerá no uso de bibliotecas JS, pessoalmente, gostaria de receber mais bibliotecas padrão.
Jacques de Hooge
1
Uma boa visão geral. No geral, o que vejo como a principal diferença (que você afirma, mas não enfatiza) é que o objetivo de Brython é realmente permitir que você use Python no navegador, enquanto parece que o objetivo de Transcrypt é permitir que você use a sintaxe Python para escrever JavaScript. Isso significa que o Transcrypt está disposto a fazer coisas como a diferença de veracidade, que se desvia em um nível básico da semântica do Python, e também parece ter como objetivo o código que aproveita as bibliotecas JavaScript; enquanto Brython tenta replicar Python o mais próximo possível com a ideia de que você fará tudo em Python.
BrenBarn de
12

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

Esta página avalia os três candidatos. Brython surge como um vencedor claro.

Apesar da 'ajuda' explicar que o SO não é bom para esse tipo de pergunta, parece que uma resposta concisa é possível neste caso.

Talvez as pessoas estejam sendo muito precipitadas?

P i
fonte
5
A última vez que verifiquei o brython não era uma implementação completa do python. Também não está claro como "melhor" ou "como escolher entre esses" deve ser medido. O mais rápido? Python não é usado principalmente para velocidade. Implementa a maioria das funções / bibliotecas? Pode haver módulos que você nunca usaria em um navegador. A sintaxe extra (não compatível com cpython) para operações comuns (manipulação de árvore) é um mais ou um menos? Não acho que o desempenho em um benchmark seja tão significativo.
syntonym
O benchmark de desempenho é um fator importante quando não é cerca de 20 a 40% mais rápido - mas sim cerca de 1000% de melhorias em algumas operações. Brython é uma camada leve sobre javascript, por isso é diferente. Além disso, o projeto é muito compatível com Python3 atualmente - o que ele faz é incorporar algumas poucas bibliotecas Javascript bem conhecidas e maduras no projeto conforme necessário, por exemplo, para manipulação de números inteiros grandes.
jsbueno
12

Eu usei e me comprometi a skulpt tão bem quanto pypyjs. E são todos três muito diferentes que qualquer comparação é discutível se você me perguntar.

Depende do que você está procurando, o que fará mais sentido.

PyPyJS

O pypyjs é enorme, é um arquivo javascript de 12 MB que contém toda a máquina virtual pypy. Portanto, se você deseja que a implementação do Python seja completa, este é o seu bebê. Ele tem uma ponte javascript que funciona muito bem, mas não é uma opção viável para escrever o código do seu site javascript em python. No entanto, vai deixar você import compiler.

Ele é construído com emscripten e é mais rápido que o CPython, ao executar o benchmark pystone.

Eu dei uma pequena palestra sobre pypyjs aqui estão os slides.

Skulpt

É uma ferramenta de ensino (ou evoluiu para isso ao longo do tempo), ele compila seu python em uma máquina de estado emulando muito de perto o compilador cpython. Em seu núcleo, é uma implementação escrita à mão do compilador python em javascript. Ele permite a execução assíncrona que permite fazer:

while (True):
    print "hi"

Sem travar o navegador.

Skulpt é o único que suporta continuações assíncronas, ele permite que você pause a execução de python enquanto ele resolve alguma coisa assíncrona para acontecer. Fazendo isso funcionar:

from time import sleep
sleep(1)

Skulpt funciona a cerca de um décimo da velocidade do CPython, ao comparar a pystone.

Brython

Eu sei menos sobre este, talvez @olemis-lang possa expandir este. Mas, além da diferença óbvia, Brython é py3 e os outros py2. Brython também é um transpiler.

Brython não executa o benchmark pystone porque time.clock não está implementado, porque oficialmente é uma função de hardware.

Albertjan
fonte
Os desenvolvedores do PyPyJS pararam o desenvolvimento. Além disso, o suporte para Python3 parece ainda inacabado. github.com/pypyjs/pypyjs/issues/213 e github.com/pypyjs/pypyjs/issues/172
Roland Pihlakas
Não é mantido, mas isso não significa que não funcione :) trinket.io/pypyjs mas preste atenção a este espaço, tenho certeza que algo vai borbulhar novamente eventualmente. Além disso, você não pode esperar que o código aberto seja mantido, a menos que você mesmo faça isso. :)
albertjan
Parece-me que o Trinket com Python 2 roda no lado do navegador, enquanto o Trinket com Python 3 (e numpy) roda no lado do servidor. Ainda é impressionante que eles consigam ter uma plotagem visual renderizada no navegador, embora o código seja executado no lado do servidor. Seria muito útil saber como eles conseguiram isso. Você tem alguma ideia?
Roland Pihlakas
1
Trinket usa a biblioteca GlowScript (glowscript.org) que usa RapydScript-NG para transpilar Python para JavaScript, e WebGL para produzir as animações 3D. Tanto a transpilação quanto a execução são feitas no navegador. Aqui está uma visão geral da arquitetura GlowScript
user1114907
7

Em primeiro lugar, sou um committer Brython. Mesmo assim, tentarei ser o mais imparcial possível para fazer uma avaliação objetiva.

A última vez que o usei, o Skulpt não suportava recursos como expressões geradoras. Brython e PyPy.js fazem isso, portanto, no nível de recurso IMHO, os últimos são superiores.

Brython (neste momento) ainda está em andamento. Alguns módulos não podem ser importados (por exemplo, xml.ElementTree ). No entanto, esta situação está começando a mudar, uma vez que estamos trabalhando para executar todo o conjunto de testes do CPython, apesar de obter compatibilidade total com os padrões (pelo menos quando faz sentido).

Brython também oferece suporte a .vfs.js para acelerar a importação de módulos.

PyPy.js tem uma série de características que decorrem diretamente do fato de ser alimentado por PyPy (compilação JIT, bem testada, ...) mas não tenho certeza se é adequado para execução no navegador. Isso pode mudar conforme o projeto evolui.

TODO: Vou tentar complementar minha resposta com benchmarks confiáveis.

Olemis Lang
fonte
8
Como um committer para skulpt, posso dizer que ele suporta expressões geradoras. :)
albertjan
6

Não mencionado aqui é RapydScript ou RapydScript-NG. Eles produzem código JavaScript muito eficiente, que é usado no GlowScript VPython (glowscript.org). Eu costumava usar o RapydScript original de Alex Tsepkov ( https://github.com/atsepkov/RapydScript ), mas recentemente mudei para RapydScript-NG de Kovid Goyal ( https://github.com/kovidgoyal/rapydscript-ng ). Recentemente, executei o benchmark pystone em CPython, RapydScript e Brython, e você pode ver os resultados aqui:

https://groups.google.com/forum/?fromgroups&hl=en#!topic/brython/20hAC9L3ayE

user1114907
fonte
Você poderia resumir os resultados?
Jay
1
Em 18 de junho, Pierre Quentel disse: "Ok, há o problema de desempenho, mas as coisas estão melhorando; a versão em que estou trabalhando atualmente (3.2.7) executa o teste de pystone 2.5 mais rápido do que 3.2.6. Ainda é 15 vezes mais lento que o CPython, mas nos primeiros dias era milhares de vezes mais lento. "
user1114907
1
Eu executei o benchmark pystones usando o transpiler rapydscript-ng, e ele comparou 5 vezes a velocidade do CPython no meu computador Windows 10, 600.000 pystones / seg vs. 125.000 pystones / seg. O fator de cerca de 5 vezes a velocidade do CPython para rapydscript-ng aumenta para cerca de 7 vezes o CPython se eu desligar a sobrecarga do operador que é usada no GlowScript VPython, no qual, por exemplo, a + b é convertido para a ["+"] (b) ; isso é feito para permitir a fácil manipulação de vetores 3D.
user1114907
Não disse que o comentário de Quentel se referia a Brython.
user1114907
2
Eu não executei mais nenhum benchmark. Eu inicialmente mudei para RapydScript-NG quando o desenvolvimento do RapydScript parou. Mais tarde, quando Alex Tsepkov voltou ao desenvolvimento, tive uma conversa com ele em que até ele concordou que o projeto NG de Kovid Goyal é mais apropriado para meu uso específico em glowscript.org. Tsepkov quer construir uma linguagem mista Python / JavaScript para programadores web, enquanto Goyal enfatiza a aproximação do Python padrão e fornece um bom suporte para compilar no navegador, sendo que ambos são essenciais para o meu trabalho.
user1114907
4

Como ninguém mencionou, achei que valeria a pena mencionar o Batavia, que implementa a máquina virtual Python para executar bytecode Python pré-compilado.

Acabei de experimentar e, embora seja um conceito interessante, ainda está nos estágios iniciais, pois há pouca documentação.

No final, vai depender do que você está tentando fazer. Escolhi Transcrypt depois de dar uma olhada porque era mais pragmático e de melhor desempenho, também lançado / mantido mais recentemente.

icarito
fonte
Skulpt ainda é mantido ativamente e usado por uma base de usuários bem grande (vários cursos polulares em cousera), ele pode não obter lançamentos tanto quanto transcrypt, mas há muito mais mantenedores, mantenedores que construíram um produto nele. Então, eles estão nisso por um longo prazo. :)
albertjan
3

Esta é uma conferência atualizada que compara todas as opções disponíveis no mercado agora:

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

O palestrante é Russel Keith-Magee, um desenvolvedor conhecido na área.

Daian Gan
fonte