浏览器中的Python:如何在Brython,PyPy.js,Skulpt和Transcrypt之间进行选择?


89

我很高兴看到现在可以在浏览器中编写Python代码了。这些是主要候选人(请添加我可能忽略的任何内容):

但是如何在它们之间进行选择?我可以看到的唯一明显区别是Skulpt基于Python 2,而Brython基于Python 3。

请注意:这不是要求提供建议或意见。我正在寻找客观的事实,以提供有根据的选择。


6
让我们为某事推荐最好的库是帮助明确说明StackOverflow不适合的情况之一。这是一个很好的问题,只是不是针对该网站的格式。您可能需要基于讨论的内容,例如邮件列表或论坛。
abarnert,2015年

2
Transcrypt(transcrypt.org)从python3.5 inc的很大一部分进行编译。多重继承,生成快速(调用备注)的小型可读代码,支持多级源映射,并且可以使用任何JS库而无需进行修改。免责声明:我写的。
雅克·德·豪格

1
嗨,fzzylogic,我已经添加了标签,所以人们现在可以使用它来询问SO的问题。用它替换了JS标记,因为如果您想在浏览器中使用Python,则它是最不可能搜索的标记。
雅克·德·豪格


1
由dstromberg删除的答案具有27个投票,有一个不错的比较链接:stromberg.dnsalias.org/~strombrg/pybrowser/python-browser.html
Cees Timmerman

Answers:


26

在浏览器中运行Python是一篇非常不错且最新的文章(截至2019年),该文章比较了Brython,Skulpt,PyPy.js,Transcrypt,Pyodide和Batavia。我强烈建议阅读。

在下面的图片中可以看到很好的总结。

在此处输入图片说明

在此处输入图片说明


61

以下是有关Brython与Transcrypt的一些信息(2016年7月,因为OP将这个问题作为选项添加了Transcrypt),几个月前与Brython开始了一个项目,然后转移到Transcrypt(上周完成),从而收集了一些信息。我喜欢Brython和Transcrypt,可以看到它们的用途。

对于对此不熟悉的人,Brython和Transcrypt都将“ transpile” Python输入转换为javascript(编辑:也许最好将Brython视为“浏览器的Python实现”,因为它不会产生独立的javascript)。两者都需要Python 3语法。Brython包含大量的Python标准库,其中一些是用于处理与Web相关的事情的,而Transcrypt在很大程度上避免了这一点,建议改用Javascript库。

布莱顿Github)可以在浏览器中进行转换。因此,您使用python编写,并且在加载页面时,brython.js引擎会将其即时转换为javascript。这确实很方便,并且比您想象的要快得多。但是,您需要在页面中包含的brython.js引擎约为500Kb。此外,还有导入标准库的问题,Brython通过使用XHR请求获取单独的.js文件来处理这些问题。有些库已经被编译到brython.js中,因此并非每次导入都会引入新文件,但是如果您使用许多导入,事情将会变慢。但是,有一些解决方法。我要做的是检查浏览器开发工具中的“网络”选项卡,以查看页面加载时正在拉入的文件,然后删除Brython src文件夹副本中我的项目未使用的所有文件,并运行Brython随附的脚本(我认为它位于Brython / www / scripts / make_VFS.py),该脚本将所有可用的库编译到一个名为py_VFS.js的文件中,您还需要从html链接到该文件。通常,它将产生一个2MB以上的巨大文件,但是如果删除不使用的内容,它可能会很小。这样,意味着您只需要拉入brython.js,py_VFS.js和您的python代码,就不需要其他XHR请求了。

另一方面,TranscryptGithub)作为python 3软件包分发您可以手动使用它,也可以将其插入工具链中,以预先将python编译为javascript。因此,使用Transcrypt,您可以使用python编写代码,对python运行transcrypt,它吐出可以链接到项目中的javascript。它也更像传统的编译器,因为它提供了对输出的一些控制。例如,您可以选择编译为ES6或ES5,或要求其输出sourcemap(在调试过程中,浏览器将您直接带到相应的python代码,其中包含生成的javascript代码。)Transcrypt的javascript输出非常简洁(或换一种说法,它又漂亮又简洁)。在我的情况下,将150kB的python转换为165kB的未缩小ES5 javascript。作为比较,转换后我项目的Brython版本使用了大约800Kb。

但是,要获得Transcrypts简洁的好处,需要稍微阅读一下文档(真的只是一点点)。例如,使用Transcrypt,默认情况下不会启用python对dict,set和list等数据结构的“真实性”,并且由于与类型检查相关的潜在性能问题,不建议在全局范围内启用它。为了清楚起见:在CPython中,空的dict,set或list的真值为False,而在Javascript中则将其视为“ true”。

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

至少有三种方法可以解决此问题:

  • 将python转换为javascript时,请使用-t标志,例如:$ transcrypt -t python.py(不建议使用,但除非在性能敏感代码的内部循环中多次检查真实性,否则可能不是问题。)
  • 在您的代码中使用__pragma__(tconv)__pragma__(notconv)来告诉Transcrypt编译器在本地开启自动转换为类似python的真值的功能。
  • 不用检查真值,而只需检查len(myList)> 0即可完全避免问题。对于大多数情况而言,这可能很好,可以轻松使用。

是的,所以我的项目越来越大,我想进行预编译以提高性能,但是发现使用Brython很难做到这一点(尽管从技术上讲是可行的,一种简单的方法是使用在线编辑器并单击javascript按钮以查看输出)。我做到了,并链接到从project.html生成的javascript,但是由于某些原因,它无法正常工作。另外,我发现很难理解来自Brython的错误消息,因此在此步骤失败后我不知道从哪里开始。同样,输出代码的大尺寸和brython引擎的尺寸也开始困扰我。因此,我决定仔细研究一下Transcrypt,它起初似乎是较高的等级,因为我更喜欢笨拙的说明来告诉我如何立即开始使用(这些内容已经添加了)。

在安装Python3.5之后进行设置的主要目的是:

  1. 使用venv(就像virtualenv的新内置版本一样,每个项目使用更少的空间)来设置python3.5项目文件夹(只需输入:python3.5 -m venv foldername- ubuntu的变通办法,其中包含3.5版的软件包问题)。这使得“ foldername”带有bin子文件夹。
  2. 使用pip安装Transcrypt python软件包(“文件夹名称/ bin / pip install tr​​anscrypt”),将其安装到foldername / lib / python3.5 / site-packages / transcrypt。
  3. activate如果您不想每次都键入foldername / bin / python3.5的完整路径,则为当前终端。输入以下内容激活:“源文件夹名称/ bin /激活”
  4. 开始编写代码并将其编译为javascript以进行测试。从编写代码的文件夹中进行编译。例如,我使用的是foldername / www / project。因此,将CD放入该文件夹并运行:'transcrypt -b your_python_script.py'。它将输出放在名为的子文件夹中__javascript__。然后,您可以从html链接到输出的javascript。

贯穿的主要问题

我的需求很简单,所以您的行程可能会有所不同。

  • 您需要用javascript库替换brython或python标准库。例如,Brython提供了“ import json”,但是在Transcrypt下,您可以使用javascript库,也可以直接在Python代码中使用JSON.parse / JSON.stringify。要在您的python代码中直接包含javascript库的缩小版本,请使用以下格式(请注意三引号):

    __pragma__ ('js', '{}', '''
    // javascript code
    ''')
    
  • Brython的html特定功能显然不适用于Transcrypt。只需使用常规的javascript方法即可。示例:1)在Brython下,您可能已经使用'document ['id']'引用了特定的HTML标记,但是使用Transcrypt时,您将使用'document.getElementById('id')(这与您执行的方法相同)它来自javascript)。2)您不能删除带有'del nodeName'(bcs是brython函数)的节点。使用类似“ node.parentNode.removeChild(node)”的名称。3)用javascript替代品替换所有brython的DOM函数。例如class_name = className; text = textContent; html = innerHTML; parent = parentNode; children = childNodes等。我想如果您需要包含某些旧版浏览器所需替代品的东西,那么这里有JavaScript库。4)Brython的set_timeout替换为javascripts setTimeout 5)Brython的html标签(例如BR())需要使用常规javascript方式替换,并重做您使用它的<= dom操作语法的任何位置。要么将纯文本标记注入为innerHTML,要么使用javascript语法制作元素,然后使用常规的javascript DOM语法附加它们。我还注意到brython对于复选框使用“ if checkbox ='checked':”,但是Transcrypt对“ if checkbox:”感到满意。要么将纯文本标记注入为innerHTML,要么使用javascript语法制作元素,然后使用常规的javascript DOM语法附加它们。我还注意到brython对于复选框使用“ if checkbox ='checked':”,但是Transcrypt对“ if checkbox:”感到满意。要么将纯文本标记注入为innerHTML,要么使用javascript语法制作元素,然后使用常规的javascript DOM语法附加它们。我还注意到brython对于复选框使用“ if checkbox ='checked':”,但是Transcrypt对“ if checkbox:”感到满意。

  • 我在上周完成了一个2700线项目的工作,当时Transcrypt不支持一些小事情(尽管它们很容易替换为填充符),这些是1)str.lower,str.split(str。拆分是存在的,但似乎是javascript拆分,它与python版本的工作方式不同,我所依赖的行为是),2)轮(现在似乎在开发版本中受支持)和3)isinstance没有在str,int和float上不起作用,仅在dict,list和set上起作用。4)与我注意到的Brython的另一个区别是,如果我输入字典的JSON表示形式,则需要使用“ myDict = dict(data)”,而Brython对“ myDict = data”感到满意。但这可能与Brython的json.loads中的某些内容有关,我直接将其替换为JSON.parse。__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或line)__pragma__('iconv'),但是您可以避免仅通过使用keys()成员来启用它,例如:

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

总结一下

  • 我喜欢Brython,因为它很容易进行并测试您的代码(仅F5)。它更接近真正的python,因为其中存在大多数标准库。我不喜欢在浏览器中包含转译引擎(编辑:或者可能会将其视为python VM)以及输出的较大javascript大小。如果我不得不做些事情(但仍然使用Brython),我会使用javascript方法来处理brython中的DOM(您可以这样做..),而不是过多地依赖brython方法,因为那浪费了时间当我的需求发生变化时,将其转移给另一个翻译。

  • 我喜欢Transcrypt,因为输出的javascript确实“精简且卑鄙”,并且加载浏览器的唯一原因是生成的javascript代码,其大小与python代码相似。也因为它支持sourcemaps,并且因为它使我对输出的javascript有一定的控制权。使用它教会了我很多关于优化的知识。

希望可以帮助某人了解其中的哪一项可能对他们的特定项目有利。


1
您确定Brython是翻译员吗?我很确定它在JavaScript中实现了Python解释器。如果是编译器,则无需将其与应用程序捆绑在一起。
卡尔·史密斯

@Carl Smith有趣的一点,没想到是那样的。Brython将python代码转换为javascript,但是由于javascript没有标准的字节码,因此也许可以将生成的javascript作为Brython引擎的“字节码”来查看。
fzzylogic

1
你误解我了。我认为Brython根本不会将Python转换为JavaScript。它只是用JS而不是C来实现Python解释器。根据他们的GitHub README,“ Brython(浏览器Python)是在浏览器中运行的Python 3的实现,具有与DOM元素和事件的接口”。
卡尔·史密斯

4
@jsbueno当前可用的是种子,randint,选择和随机,它们只是作为起点。实际上,我们希望有人能够将其拾起并完成它,就像在re上所做的一样,这在我们的清单上排名很高。不应该那么难。图书馆的数量有所增加,但是贡献很大。尽管将继续强调使用JS库,但我个人还是欢迎更多的标准库。
雅克·德·豪格

1
一个不错的概述。总的来说,我看到的主要区别(您声明但不强调)是Brython的目标实际上是让您在浏览器中使用Python,而Transcrypt的目标似乎是让您使用Python语法编写JavaScript。这意味着Transcrypt愿意做诸如真实性差异之类的事情,这些差异在基本层面上与Python语义有所不同,并且似乎针对利用JavaScript库的代码。而Brython尝试使用Python做所有事情,从而尽可能地复制Python。
BrenBarn

12

我已经使用并致力于skpy和pypyjs。这三个都是非常不同的,如果您问我,那么任何比较都没有意义。

这取决于您要寻找的是最有意义的。

PyPyJS

pypyjs很大,它是一个12MB的javascript文件,其中包含整个pypy虚拟机。因此,如果您希望python实现的完整性,这是您的宝贝。它具有一个非常好的javascript桥接器,但不是用python编写javascript网站代码的可行选择。但是它将让您import compiler

它使用emscripten构建,并且在运行pystone基准测试中CPython更快

我简短介绍了pypyjs,这里是幻灯片。

骷髅

它是一种教学工具(或者随着时间的推移已经发展成为一种工具),它可以将您的python编译为非常类似于cpython编译器的状态机。它的核心是javascript中python编译器的手写实现。它允许异步执行,您可以执行以下操作:

while (True):
    print "hi"

无需锁定浏览器。

Skulpt是唯一支持异步连续的人,它可以让您在解决某些异步事件的同时暂停python的执行。使这项工作:

from time import sleep
sleep(1)

比较pystone时,Skulpt的运行速度约为CPython的十分之一。

布莱顿

我对此至少一无所知,也许@ olemis-lang可以扩大这一范围。但是除了明显的区别,Brython是py3,其他是py2。Brython还是译者。

Brython不运行pystone基准测试,因为未实现time.clock,因为正式地说,它是硬件功能。


PyPyJS开发人员已停止开发。此外,Python3支持似乎仍未完成。github.com/pypyjs/pypyjs/issues/213github.com/pypyjs/pypyjs/issues/172
Roland Pihlakas

它没有得到维护,但这并不意味着它不起作用:) trinket.io/pypyjs,但是请注意这个空间,我很确定最终会再次冒出气泡。另外,除非您自己进行维护,否则您不能期望开源会得到维护。:)
albertjan

在我看来,带有Python 2的Trinket在浏览器端运行,而带有Python 3(和numpy)的Trinket在服务器端运行。即使代码在服务器端运行,他们仍然设法在浏览器中呈现可视化图,这仍然令人印象深刻。了解他们如何实现这一目标将非常有用。你有什么想法?
罗兰·皮拉卡斯

Trinket使用GlowScript库(glowscript.org),该库使用RapydScript-NG将Python转换为JavaScript,并使用WebGL生成3D动画。编译和执行都在浏览器中完成。以下是GlowScript架构的概述:vpython.org/contents/VPythonArchitecture.pdf
user1114907

11

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

该页面对这三个候选人进行了基准测试。Brython显然是赢家。

尽管“帮助”解释了SO不适用于此类问题,但在这种情况下,简洁的答案似乎是可能的。

也许人们太草率了?


5
上次我检查brython时,它不是python的完整实现。还不清楚应该如何衡量“最佳”或“如何在这些之间进行选择”。最快的?Python通常不用于提高速度。实现大多数功能/库?某些模块可能永远不会在浏览器中使用。是普通操作(树操作)的额外(与cpython不兼容)语法是加号还是减号?我认为基准测试中的性能没有意义。
同义词

如果性能基准测试的速度不是快20%到40%,而是在某些操作中提高了大约1000%,则是一个重要的因素。Brython是javascript上的轻量级图层,因此有所不同。另外,如今该项目非常符合Python3的规范-它的作用是根据需要在项目中合并一些,知名且成熟的Javascript库,例如用于大整数处理。
jsbueno 2015年

7

首先,我是Brython的提交者。但是为了进行客观评估我会尽量保持公正。

我上次使用它时,Skulpt不支持生成器表达式之类的功能。Brython和PyPy.js这样做,因此在IMHO的功能级别上,后者要好一些。

Brython(此时)仍在进行中。某些模块无法导入(例如xml.ElementTree)。尽管如此,这种情况开始改变,因为尽管我们实现了与标准的完全兼容性(至少在合理的情况下),但我们正在努力运行整个CPython测试套件。

Brython还支持.vfs.js来加快模块导入。

由于PyPy.js由PyPy提供支持(JIT编译,经过良好测试,...),因此具有许多直接的特征,但是我不确定它是否适合在浏览器中运行。随着项目的发展,这可能会改变。

待办事项:我将尝试用可靠的基准来补充我的答案。


8
作为速写的提交者,我可以告诉您它确实支持生成器表达式。:)
albertjan

6

这里没有提到RapydScript或RapydScript-NG。它们产生非常有效的JavaScript代码,该代码在GlowScript VPython(glowscript.org)中使用。我曾经使用过Alex Tsepkov的原始RapydScript(https://github.com/atsepkov/RapydScript),但是最近切换到Kovid Goyal的RapydScript-NG(https://github.com/kovidgoyal/rapydscript-ng)。我最近在CPython,RapydScript和Brython上运行了pystone基准测试,您可以在这里查看结果:

https://groups.google.com/forum/?fromgroups&hl=zh-CN#topic/brython/20hAC9L3ayE


您可以总结一下结果吗?
周杰伦

1
Pierre Quentel在6月18日说:“好,这是性能问题,但是情况正在变得更好;我正在开发的版本(3.2.7)运行pystone test 2.5的速度比3.2.6快。仍然是15速度比CPython慢​​了十倍,但在早期,它慢了数千倍。”
user1114907

1
我使用rapydscript-ng Transpiler运行了pystones基准测试,它对Windows 10计算机上CPython的速度进行了5倍的基准测试,即600000 pystones / sec与125000 pystones / sec。如果我关闭在GlowScript VPython中使用的运算符重载(例如,其中a + b转换为a [“ +”](b),则rapydscript-ng的CPython速度的5倍将增加到CPython的7倍)。 ; 这样做是为了容易操作3D向量。
user1114907

我没有说昆特尔的评论提到了布莱顿。
user1114907

2
我没有再运行任何基准测试。当RapydScript的开发停滞时,我最初切换到RapydScript-NG。然后,当Alex Tsepkov恢复开发时,我与他进行了一次交流,甚至在他同意Kovid Goyal的NG项目更适合我在glowscript.org上的特定用途时。Tsepkov希望为Web程序员构建一种混合的Python / JavaScript语言,而Goyal则强调近似标准的Python,并为在浏览器中进行编译提供了良好的支持,这两者都是我工作的关键。
user1114907

4

由于没有人提到它,所以我认为值得提及Batavia,它实现了用于运行预编译的Python字节码的Python虚拟机。

我只是尝试了一下,尽管它是一个有趣的概念,但由于文档很少,它仍处于早期阶段。

最后,这取决于您要做什么。我看了一下就选择了Transcrypt,因为它更加实用,性能更好,而且也是最近发布/维护的。


Skulpt仍然由相当大的用户群(在cousera上有许多非常讲究的课程)积极维护和使用,它可能无法获得比transcrypt发行版那么多的发行版,但是有更多的维护者,维护者正在其上构建产品。因此,从长远来看,他们会加入其中。:)
albertjan '17

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.