Python nel browser: come scegliere tra Brython, PyPy.js, Skulpt e Transcrypt?


91

Sono molto entusiasta di vedere che ora è possibile codificare Python nel browser. Questi sono i candidati principali (aggiungi quelli che potrei aver trascurato):

Ma come scegliere tra loro? L'unica differenza evidente che posso vedere è che Skulpt è basato su Python 2, mentre Brython è basato su Python 3.

Nota: questa non è una richiesta di consigli o opinioni. Cerco fatti oggettivi che informino una scelta consapevole.


6
Chiederci di consigliare la migliore libreria per qualcosa è uno dei casi in cui l'aiuto spiega esplicitamente che StackOverflow non è adatto. È un'ottima domanda, solo non per il formato di questo sito; probabilmente vuoi qualcosa di basato sulla discussione, come una mailing list o un forum.
abarnert

2
Transcrypt ( transcrypt.org ) viene compilato da un ampio sottoinsieme di python3.5 inc. ereditarietà multipla, genera codice veloce (call memoizing), piccolo e leggibile, supporta mappe sorgenti multilivello e può utilizzare qualsiasi libreria JS senza adattamento. Disclaimer: l'ho scritto.
Jacques de Hooge

1
Ciao fzzylogic, ho aggiunto il tag, quindi ora le persone possono fare domande su SO utilizzandolo. Sostituito il tag JS da esso, perché è il meno probabile su cui cercare se preferisci usare Python nel browser.
Jacques de Hooge

1
Ho scritto una specie di tutorial per Transcrypt per principianti. Puoi guardarlo su github.com/bunkahle/Transcrypt-Examples/blob/master/alerts/… e github.com/bunkahle/Transcrypt-Examples/blob/master/cookies/…
bunkus

1
La risposta eliminata di dstromberg con 27 voti positivi ha un bel link di confronto: stromberg.dnsalias.org/~strombrg/pybrowser/python-browser.html
Cees Timmerman,

Risposte:


30

L'esecuzione di Python nel browser è un articolo davvero buono e aggiornato (al 2019) che mette a confronto Brython, Skulpt, PyPy.js, Transcrypt, Pyodide, Batavia . Consiglio vivamente di leggerlo.

Un buon riassunto può essere visto nelle immagini seguenti.

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine


62

Ecco alcune informazioni su Brython vs Transcrypt (luglio 2016, poiché Transcrypt è stato aggiunto come opzione su questa domanda dall'OP), raccolte avviando un progetto con Brython alcuni mesi fa e passando a Transcrypt (completato lo spostamento la scorsa settimana). Mi piacciono Brython e Transcrypt e posso vedere gli usi per entrambi.

Per le persone che sono nuove a questo, Brython e Transcrypt entrambi 'transpile' input python in javascript (Modifica: forse è meglio vedere Brython come una 'implementazione Python per il browser' perché non produce javascript autonomo). Entrambi richiedono la sintassi di Python 3. Brython include un numero sostanziale di librerie standard Python e alcune delle sue per gestire le cose relative al web, mentre Transcrypt lo evita per la maggior parte e suggerisce di utilizzare invece le librerie Javascript.

Brython ( Github) può eseguire la conversione nel browser. Quindi scrivi in ​​python e il motore brython.js lo converte in javascript al volo quando la pagina viene caricata. Questo è davvero comodo ed è molto più veloce di quanto potresti pensare. Tuttavia, il motore brython.js che devi includere nelle tue pagine è di circa 500Kb. Inoltre, c'è la questione dell'importazione di librerie standard, che Brython gestisce recuperando file .js separati con richieste XHR. Alcune librerie sono già compilate in brython.js, quindi non tutte le importazioni attireranno nuovi file, ma se si utilizzano molte importazioni, le cose possono rallentare. Tuttavia, ci sono modi per aggirare questo problema. Quello che ho fatto è stato controllare la scheda di rete negli strumenti di sviluppo del browser per vedere quali file venivano inseriti quando la pagina è stata caricata, quindi eliminare tutti i file che il mio progetto non stava utilizzando in una copia della cartella Brython src, ed esegui lo script incluso con Brython (penso sia su Brython / www / scripts / make_VFS.py) che compila tutte le librerie disponibili in un file chiamato py_VFS.js a cui devi anche collegarti dal tuo html. Normalmente, creerà un enorme file da 2 MB +, ma se elimini le cose che non stai utilizzando, può essere piuttosto piccolo. In questo modo, significa che devi solo inserire brython.js, py_VFS.js e il tuo codice Python e non saranno necessarie ulteriori richieste XHR.

Transcrypt ( Github ) d'altra parte, è distribuito come pacchetto python 3che puoi usare manualmente, o agganciarti alla tua toolchain, per compilare in anticipo python in javascript. Quindi con Transcrypt, scrivi in ​​python, esegui transcrypt contro il python e sputa javascript a cui puoi collegarti nel tuo progetto. È più simile a un compilatore tradizionale anche in quanto offre un certo controllo sull'output. Ad esempio, puoi scegliere di compilare su ES6 o ES5, o chiedergli di generare mappe sorgente (che durante il debug lascia che il browser ti porti direttamente al codice Python corrispondente, all'interno del codice javascript generato). L'output javascript di Transcrypt è piuttosto conciso ( o in altre parole, è carino e conciso). Nel mio caso 150kB di python vengono convertiti in 165kB di javascript ES5 non minimizzato. A titolo di confronto, la versione Brython del mio progetto utilizzava circa 800Kb dopo la conversione.

Tuttavia, per ottenere i vantaggi della concisione di Transcrypts, è necessario leggere un po 'i documenti (davvero solo un po'). Ad esempio, con Transcrypt, la "veridicità" di Python per strutture di dati come dict, set e list non è abilitata per impostazione predefinita e l'abilitazione globale è sconsigliata a causa di potenziali problemi di prestazioni legati al controllo dei tipi. Per chiarezza: in CPython, un dict, un insieme o un elenco vuoto ha il valore di verità False, mentre in Javascript è considerato "vero". Esempio:

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

Esistono almeno tre modi per risolvere questo problema:

  • Usa il flag -t quando converti python in javascript, ad esempio: $ transcrypt -t python.py (non consigliato, ma probabilmente non è un problema a meno che tu non controlli la veridicità molte volte nei cicli interni di codice sensibile alle prestazioni ..)
  • Usa __pragma__(tconv)o __pragma__(notconv)all'interno del codice per dire al compilatore transcrypt di attivare la conversione automatica in valori di verità simili a python localmente.
  • Invece di controllare il valore di verità, evita del tutto il problema semplicemente controllando len (myList)> 0 ... Forse andrà bene per la maggior parte delle situazioni, fa il lavoro per il mio uso leggero.

Giusto, quindi il mio progetto stava diventando più grande e volevo precompilare per migliorare le prestazioni, ma ho trovato difficile farlo con Brython (sebbene sia tecnicamente possibile, un modo semplice è usare l' editor online e fare clic sul pulsante javascript per vedere Il risultato). L'ho fatto e mi sono collegato al javascript generato da project.html ma non ha funzionato per qualche motivo. Inoltre, trovo difficile capire i messaggi di errore di Brython, quindi non sapevo da dove iniziare dopo che questo passaggio non è riuscito. Inoltre, la grande dimensione del codice emesso e la dimensione del motore Brython cominciavano a darmi fastidio. Quindi ho deciso di dare un'occhiata più da vicino a Transcrypt, che all'inizio sembrava essere di livello superiore perché preferisco istruzioni stupide che mi dicono come iniziare immediatamente (queste sono state aggiunte da allora).

La cosa principale per impostarlo dopo l'installazione di Python3.5 era:

  1. Usa venv (è come una nuova versione integrata di virtualenv che utilizza meno spazio per ogni progetto) per configurare una cartella di progetto python3.5 (basta digitare: python3.5 -m nome cartella venv - soluzione alternativa per ubuntu con problemi di pacchetto per 3.5 ). Questo rende 'nomecartella' con una sottocartella bin tra le altre cose.
  2. Installa il pacchetto Transcrypt python con pip ('nomecartella / bin / pip install transcrypt') che lo installa in nomecartella / lib / python3.5 / site-packages / transcrypt.
  3. activateil terminale corrente se non si desidera dover digitare il percorso completo di nomecartella / bin / python3.5 ogni volta. Attiva digitando: "nome cartella di origine / bin / attivare"
  4. Inizia a scrivere codice e compilarlo in javascript per il test. Compila dalla cartella in cui scrivi il tuo codice. Ad esempio, ho usato nomecartella / www / progetto. Quindi CD in quella cartella ed esegui: "transcrypt -b your_python_script.py". Questo mette l'output in una sottocartella chiamata __javascript__. Puoi quindi collegarti al javascript emesso dal tuo html.

Principali problemi in corso

Ho esigenze piuttosto semplici, quindi il tuo chilometraggio potrebbe variare.

  • È necessario sostituire le librerie standard brython o python con librerie javascript. Quindi, ad esempio, "import json" è fornito da Brython, ma in Transcrypt è possibile utilizzare una libreria javascript o semplicemente utilizzare JSON.parse / JSON.stringify direttamente nel codice Python. Per includere una versione minimizzata di una libreria javascript direttamente nel tuo codice python usa questo formato (nota le virgolette triple):

    __pragma__ ('js', '{}', '''
    // javascript code
    ''')
    
  • Ovviamente le funzioni html specifiche di Brython non funzionano con Transcrypt. Usa i normali metodi javascript. Esempi: 1) in Brython, potresti aver fatto riferimento a un tag HTML specifico usando 'document [' id ']', ma con Transcrypt avresti usato 'document.getElementById (' id ') (che è lo stesso modo da javascript). 2) Non puoi eliminare un nodo con 'del nodeName' (bcs che è una funzione brython). Usa qualcosa come 'node.parentNode.removeChild (node)'. 3) sostituire tutte le funzioni DOM di brython con le alternative javascript. ad es. class_name = className; text = textContent; html = innerHTML; parent = parentNode; children = childNodes ecc. Immagino che se hai bisogno di qualcosa che contenga alternative richieste da alcuni browser meno recenti, allora ci sono librerie javascript per questo. 4) Il set_timeout di Brython è sostituito con javascripts setTimeout 5) I tag html di Brython come BR () devono essere sostituiti usando i normali metodi di javascript così come rifare qualsiasi posto che hai usato è la sintassi di manipolazione <= dom. Iniettare il markup di testo normale come innerHTML o creare gli elementi utilizzando la sintassi javascript e quindi allegarli utilizzando la normale sintassi DOM javascript. Ho anche notato che per le caselle di controllo brython usa "if checkbox = 'checks':" ma Transcrypt è soddisfatto di "if checkbox:" .. Iniettare il markup di testo normale come innerHTML o creare gli elementi utilizzando la sintassi javascript e quindi allegarli utilizzando la normale sintassi DOM javascript. Ho anche notato che per le caselle di controllo brython usa "if checkbox = 'checks':" ma Transcrypt è soddisfatto di "if checkbox:" .. Iniettare il markup di testo normale come innerHTML o creare gli elementi utilizzando la sintassi javascript e quindi allegarli utilizzando la normale sintassi DOM javascript. Ho anche notato che per le caselle di controllo brython usa "if checkbox = 'checks':" ma Transcrypt è soddisfatto di "if checkbox:" ..

  • Ho finito di spostare un progetto a 2700 linee la scorsa settimana, momento in cui Transcrypt non aveva il supporto per alcune cose minori (sebbene fossero abbastanza facili da sostituire con i riempitivi), questi erano 1) str.lower, str.split (str. split è presente, ma sembra essere lo split javascript, che funziona in modo diverso rispetto alla versione python, il cui comportamento mi basavo), 2) round (questo sembra essere supportato nella versione dev ora) e 3) isinstance didn non funziona su str, int e float, solo su dict, list e set. 4) Un'altra differenza da Brython che ho notato è che se inserisco una rappresentazione JSON di un dict, devo farlo usando 'myDict = dict (data)', mentre brython era soddisfatto di 'myDict = data'. Ma questo potrebbe essere correlato a qualcosa in json.loads di Brython, che ho sostituito direttamente con JSON.parse.__pragma__('opov')per local), non puoi fare cose come le operazioni sugli insiemi usando il formato sovraccarico, ma devi usare le funzioni corrispondenti. Per esempio

    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) Inoltre, non puoi iterare dict per impostazione predefinita usando 'for i in dict:', senza abilitarlo (riga cmd -i o __pragma__('iconv'), ma puoi evitare di doverlo abilitare semplicemente usando il membro keys () es:

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

Riassumere

  • Mi piace Brython perché è facile utilizzarlo e testare il codice (solo F5). È più vicino al vero python perché la maggior parte della libreria standard è lì. Non mi piace dover includere il motore di transpilation (Modifica: oppure si potrebbe vederlo come una VM Python) nel browser e le grandi dimensioni javascript emesse. Se avessi dovuto fare le cose (ma ancora usando Brython), avrei usato i metodi javascript per manipolare il DOM da brython (cosa che puoi fare ..), invece di appoggiarti così tanto ai metodi brython perché quello spreca tempo a spostarsi a un altro trasportatore quando le mie esigenze sono cambiate.

  • Mi piace Transcrypt perché il javascript emesso è davvero "snello e meschino" e perché l'unica cosa che carichi lato browser è il tuo codice javascript generato che è di dimensioni simili al tuo codice python. Anche perché supporta le mappe sorgente e perché mi dà una misura di controllo sul javascript emesso. E usarlo mi ha insegnato parecchio sull'ottimizzazione.

Spero che questo aiuti qualcuno a capire quale di questi potrebbe essere utile per il suo particolare progetto.


1
Sei sicuro che Brython sia un transpiler? Sono abbastanza sicuro che implementa un interprete Python in JavaScript. Se fosse un transpiler, non avresti bisogno di raggrupparlo con la tua app.
Carl Smith

@Carl Smith Punto interessante, non ci avevo pensato così. Brython converte il codice python in javascript, ma poiché javascript non ha un bytecode standard, forse si potrebbe visualizzare il javascript generato come "bytecode" per il motore Brython.
fzzylogic

1
Mi hai frainteso. Non penso affatto che Brython transpili Python in JavaScript. Implementa solo un interprete Python in JS, invece di C. Secondo il loro README GitHub "Brython (Browser Python) è un'implementazione di Python 3 in esecuzione nel browser, con un'interfaccia per gli elementi DOM e gli eventi".
Carl Smith

4
@jsbueno Attualmente sono disponibili seed, randint, choice e random, che sono intesi solo come punto di partenza. In realtà speriamo che qualcuno lo raccolga e lo completi, come è stato fatto per re, che era in cima alla nostra lista. Non dovrebbe essere così difficile. La quantità di biblioteche è aumentata ma i contributi sono molto graditi. Sebbene l'accento rimarrà sull'uso delle librerie JS, personalmente accolgo con favore più librerie standard.
Jacques de Hooge

1
Una bella panoramica. Nel complesso, quella che vedo come la differenza principale (che dichiari ma non enfatizzi) è che l'obiettivo di Brython è in realtà quello di farti usare Python nel browser, mentre sembra che l'obiettivo di Transcrypt sia quello di farti usare la sintassi di Python per scrivere JavaScript. Ciò significa che Transcrypt è disposto a fare cose come la differenza di verità che deviano a un livello base dalla semantica di Python, e sembra anche essere mirata al codice che sfrutta le librerie JavaScript; mentre Brython cerca di replicare Python il più fedelmente possibile con l'idea che farai tutto in Python.
BrenBarn

12

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

Questa pagina confronta i tre candidati. Brython emerge come un chiaro vincitore.

Nonostante l '"aiuto" che spiega che SO non va bene per questo tipo di domande, sembra che in questo caso sia possibile una risposta concisa.

Forse le persone sono troppo frettolose?


5
L'ultima volta che ho controllato brython non era un'implementazione completa di python. Inoltre non è chiaro come misurare il "meglio" o il "come scegliere tra questi". Il più veloce? Python per lo più non viene utilizzato per la velocità. Implementa la maggior parte delle funzioni / librerie? Potrebbero esserci moduli che non useresti mai in un browser. La sintassi extra (non compatibile con cpython) per le operazioni comuni (manipolazione dell'albero) è un più o un meno? Non penso che la performance in un benchmark sia così significativa.
syntonym

Il benchmark delle prestazioni è un fattore importante quando non è circa il 20-40% più veloce, ma piuttosto il 1000% circa di miglioramenti in alcune operazioni. Brython è uno strato leggero su JavaScript, quindi è diverso. Inoltre, il progetto è molto conforme a Python3 in questi giorni: ciò che fa è incorporare alcune poche, ben note e mature librerie Javascript nel progetto secondo necessità, ad esempio per la gestione di grandi numeri interi.
jsbueno

12

Ho usato e mi sono impegnato a skulpt e pypyjs. E sono tutti e tre molto diversi che qualsiasi confronto è discutibile se me lo chiedi.

Dipende da cosa stai cercando quale avrà più senso.

PyPyJS

pypyjs è enorme, è un file javascript da 12 MB che contiene l'intera macchina virtuale pypy. Quindi, se vuoi la completezza dell'implementazione di Python, questo è il tuo bambino. Ha un bridge javascript che funziona davvero bene ma non è un'opzione valida per scrivere il codice del tuo sito web javascript in python. Ti lascerà comunque import compiler.

È costruito con emscripten ed è più veloce di CPython, nell'esecuzione del benchmark pystone.

Ho fatto un breve discorso su pypyjs qui ci sono le diapositive.

Skulpt

È uno strumento di insegnamento (o si è evoluto in quello nel tempo), compila il tuo python in una macchina a stati che emula molto da vicino il compilatore cpython. Fondamentalmente è un'implementazione scritta a mano del compilatore python in javascript. Consente l'esecuzione asincrona che ti consente di fare:

while (True):
    print "hi"

Senza bloccare il browser.

Skulpt è l'unico che supporta le continuazioni asincrone, ti consente di sospendere l'esecuzione di python mentre sta risolvendo alcune cose asincrone che accadono. Fare questo lavoro:

from time import sleep
sleep(1)

Skulpt funziona a circa un decimo della velocità di CPython, quando si confronta pystone.

Brython

Conosco meno questo forse @ olemis-lang può espandere questo. Ma accanto all'ovvia differenza che Brython è py3 e gli altri py2. Brython è anche un transpiler.

Brython non esegue il benchmark pystone perché time.clock non è implementato, perché ufficialmente è una funzione hardware.


Gli sviluppatori di PyPyJS hanno interrotto lo sviluppo. Anche il supporto per Python3 sembra ancora incompleto. github.com/pypyjs/pypyjs/issues/213 e github.com/pypyjs/pypyjs/issues/172
Roland Pihlakas

Non è mantenuto, ma ciò non significa che non funzioni :) trinket.io/pypyjs ma guarda questo spazio sono abbastanza sicuro che alla fine qualcosa tornerà a galla . Inoltre non puoi aspettarti che l'open source venga mantenuto, a meno che tu non lo faccia da solo. :)
albertjan

Mi sembra che Trinket con Python 2 venga eseguito sul lato browser, mentre Trinket con Python 3 (e numpy) venga eseguito sul lato server. È comunque impressionante che riescano a rendere il plottaggio visivo reso nel browser, anche se il codice viene eseguito sul lato server. Sarebbe molto utile sapere come ci sono riusciti. Hai qualche idea?
Roland Pihlakas

1
Trinket utilizza la libreria GlowScript (glowscript.org) che utilizza RapydScript-NG per trasferire Python in JavaScript e WebGL per produrre le animazioni 3D. Sia il transpiling che l'esecuzione avvengono nel browser. Ecco una panoramica dell'architettura GlowScript
user1114907

7

Prima di tutto sono un committer di Brython. Tuttavia cercherò di essere il più imparziale possibile per fare una valutazione obiettiva.

L'ultima volta che l'ho usato, Skulpt non supportava funzionalità come le espressioni del generatore. Brython e PyPy.js lo fanno, quindi a livello di funzionalità IMHO i successivi sono superiori.

Brython (in questo momento) è ancora in lavorazione. Alcuni moduli non possono essere importati (ad esempio xml.ElementTree ). Tuttavia questa situazione sta iniziando a cambiare poiché stiamo lavorando per eseguire l'intera suite di test CPython nonostante il raggiungimento della piena compatibilità con gli standard (almeno quando ha senso).

Brython supporta anche .vfs.js per velocizzare le importazioni dei moduli.

PyPy.js ha una serie di caratteristiche che derivano direttamente dal fatto che è alimentato da PyPy (compilazione JIT, ben testata, ...) ma non sono sicuro che sia adatto per l'esecuzione nel browser. Questo potrebbe cambiare con l'evolversi del progetto.

TODO: Cercherò di integrare la mia risposta con benchmark affidabili.


8
Come committer per skulpt posso dirti che supporta le espressioni del generatore. :)
albertjan

6

Non menzionato qui è RapydScript o RapydScript-NG. Producono codice JavaScript molto efficiente, che viene utilizzato in GlowScript VPython (glowscript.org). Usavo il RapydScript originale di Alex Tsepkov ( https://github.com/atsepkov/RapydScript ) ma recentemente sono passato a RapydScript-NG di Kovid Goyal ( https://github.com/kovidgoyal/rapydscript-ng ). Di recente ho eseguito il benchmark pystone su CPython, RapydScript e Brython e puoi vedere i risultati qui:

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


Potresti riassumere i risultati?
Jay

1
Il 18 giugno, Pierre Quentel ha dichiarato: "Ok, c'è il problema delle prestazioni, ma le cose stanno migliorando; la versione su cui sto lavorando (3.2.7) esegue il test pystone 2.5 più velocemente della 3.2.6. È ancora 15 volte più lento di CPython, ma nei primi tempi era migliaia di volte più lento. "
user1114907

1
Ho eseguito il benchmark pystones utilizzando il transpiler rapydscript-ng e ha confrontato 5 volte la velocità di CPython sul mio computer Windows 10, 600000 pystones / sec contro 125000 pystones / sec. Il fattore di circa 5 volte la velocità di CPython per rapydscript-ng aumenta a circa 7 volte CPython se disattivo il sovraccarico degli operatori che viene utilizzato in GlowScript VPython, in cui ad esempio a + b viene convertito a ["+"] (b) ; questo viene fatto per consentire una facile manipolazione dei vettori 3D.
user1114907

Non sono riuscito a dire che il commento di Quentel si riferiva a Brython.
user1114907

2
Non ho più eseguito benchmark. Inizialmente sono passato a RapydScript-NG quando lo sviluppo di RapydScript si è bloccato. Successivamente, quando Alex Tsepkov è tornato allo sviluppo, ho avuto uno scambio con lui in cui anche lui ha convenuto che il progetto NG di Kovid Goyal è più appropriato per il mio uso particolare su glowscript.org. Tsepkov vuole costruire un linguaggio misto Python / JavaScript per programmatori web, mentre Goyal enfatizza l'approssimazione dello standard Python e fornisce un buon supporto per la compilazione nel browser, entrambi fondamentali per il mio lavoro.
user1114907

4

Dato che nessuno lo ha menzionato, ho pensato che valesse la pena menzionare Batavia che implementa la macchina virtuale Python per eseguire il bytecode Python precompilato.

L'ho appena provato e, sebbene sia un concetto interessante, è ancora nelle fasi iniziali poiché c'è poca documentazione.

Alla fine dipenderà da quello che stai cercando di fare. Ho scelto Transcrypt dopo aver dato un'occhiata perché era più pragmatico e più performante, anche più recentemente rilasciato / mantenuto.


Skulpt è ancora attivamente mantenuto e utilizzato da una base di utenti piuttosto ampia (diversi corsi molto diffusi su cousera) potrebbe non ottenere rilasci tanto quanto la transcriptazione, ma ci sono molti più manutentori, manutentori che hanno costruito un prodotto su di esso. Quindi ci stanno dentro a lungo termine. :)
albertjan

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.