Python中的浏览器:如何selectBrython,PyPy.js,Skulpt和Transcrypt?

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

  • Brython
  • Skulpt
  • PyPy.js
  • Transcrypt

但如何select它们呢? 我能看到的唯一明显的区别是Skulpt基于Python 2,而Brython基于Python 3。

请注意: 这不是一个build议或意见的要求。 我正在寻求客观的事实,通知一个受过教育的select。

这可能也有帮助: http : //stromberg.dnsalias.org/~strombrg/pybrowser/python-browser.html

它比较了几种Python中的浏览器技术。

这里有一些关于Brython vs Transcrypt的信息(2016年7月,由于OPjoin了Transcrypt作为这个问题的一个选项),几个月前从Brython开始一个项目,转移到Transcrypt(上周完成)。 我喜欢Brython和Transcrypt,可以看到他们两个的用途。

对于新手来说,Brython和Transcrypt都将“transpile”pythoninput到javascript中(编辑:也许最好将Brython视为“浏览器的Python实现”,因为它不会产生独立的javascript)。 两者都需要Python 3语法。 Brython包含了大量的Python标准库,还有一些用于处理与networking有关的东西,而Transcrypt大部分避免了这种情况,并build议使用Javascript库。

Brython ( Github )可以在浏览器中进行转换。 所以你用python编写,当页面加载时,brython.js引擎会将其转换为javascript。 这真的很方便,比你想象的要快得多。 但是,您需要在页面中包含的brython.js引擎大约为500Kb。 还有,导入标准库是Brython通过XHR请求获取单独的.js文件来处理的。 有些库已经编译到brython.js中,所以不是每个导入都会引入新的文件,但是如果你使用了很多导入,事情会变得很慢。 但是,有这方面的方法。 我所做的是检查浏览器开发工具中的networking选项卡,以查看加载页面时正在拉什么文件,然后删除项目未在Brython src文件夹副本中使用的所有文件,然后运行脚本包含在Brython(我认为它是在Brython / www / scripts / make_VFS.py),将所有可用的库编译成一个名为py_VFS.js的文件,你也需要链接到你的html。 通常情况下,它会创build一个巨大的2MB +文件,但是如果删除了不使用的东西,则可能会非常小。 这样做,意味着你只需要拉入brython.js,py_VFS.js和你的python代码,不需要额外的XHR请求。

另一方面, Transcrypt ( Github )是作为一个python 3包分发的,你可以手动使用,或者挂钩到你的工具链中,提前将python编译成javascript。 所以用Transcrypt,你用python编写,对python运行transcrypt,它会吐出你可以链接到你的项目的javascript。 它更像是一个传统的编译器,它提供了对输出的一些控制。 例如,您可以select编译为ES6或ES5,或者要求它输出源代码(在debugging期间,让我们的浏览器直接转到相应的python代码,生成的javascript代码的insead。)Transcrypt的javascript输出非常简洁或换句话说,这是可爱的和简洁的)。 在我的情况下,150kB的python被转换为165kB的未定义的ES5 javascript。 通过比较,我的项目的Brython版本转换后使用了大约800Kb。

但是,获得Transcrypts简洁的好处,需要阅读一些文档(实际上只是一点点)。 例如,对于Transcrypt,Python对dict,set和list等数据结构的“真实性”默认情况下是不启用的,而且由于与types查询相关的潜在性能问题,全局启用它是不鼓励的。 为了清楚起见,在CPython下,一个空字典,集合或列表的真值为False,而在JavaScript中,它被认为是“真”。例如:

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

至less有三种方法可以解决这个问题:

  • 在将python转换为javascript时使用-t标志例如:$ transcrypt -t python.py(不推荐,但是可能不是问题,除非你在性能敏感代码的内部循环中多次检查真实性)
  • 在代码中使用__pragma__(tconv)__pragma__(notconv)告诉__pragma__(notconv)编译器在本地自动转换为类似python的真值。
  • 而不是检查真值,只要检查len(myList)> 0 …就可以完全避免这个问题。也许这对大多数情况来说都可以,我的光源使用这个工作。

对,所以我的项目变得越来越大了,我想预编译一个性能增益,但发现很难用Brython来做(尽pipe这在技术上是可行的,一个简单的方法就是使用在线编辑器并点击javascriptbutton来查看输出)。 我做到了这一点,并链接到从project.html生成的JavaScript,但由于某种原因,它没有工作。 另外,我发现很难理解来自Brython的错误消息,所以在这一步失败后我不知道该从哪里开始。 而且,输出代码的大尺寸和brython引擎的大小开始让我烦恼。 所以我决定仔细研究一下Transcrypt,它起初看起来比较高级,因为我更喜欢笨拙的指令,告诉我如何立即开始(这些已经被添加)。

在安装Python3.5之后设置它的主要原因是:1)使用venv(就像virtualenv的一个新的内置版本,它为每个项目使用更less的空间)build立一个python3.5项目文件夹(只需键入:python3 .5 -m venv文件夹名称 – 解决ubuntu与包问题为3.5 )。 这使得“文件夹名”与bin子文件夹等等。 2)使用pip('foldername / bin / pip install tr​​anscrypt')安装Transcrypt python软件包,将其安装到foldername / lib / python3.5 / site-packages / transcrypt。 3)如果您不想每次都键入到foldername / bin / python3.5的完整path,请激活当前terminal。 激活键入:'源文件夹名称/ bin /激活'4)开始编写代码并编译为JavaScript进行testing。 从您编写代码的文件夹内编译。例如,我使用了foldername / www / project。 所以把光盘放到那个文件夹里,运行:'transcrypt -b your_python_script.py'。 这将输出放在名为__javascript__的子文件夹中。 然后,您可以链接到您的HTML输出的JavaScript。

主要问题横跨

我有相当简单的需求,所以你的里程可能会有所不同。

  • 您需要用JavaScript库replacebrython或python标准库。 因此,例如“import json”是由Brython提供的,但是在Transcrypt下,您可以使用JavaScript库,或者直接在您的Python代码中使用JSON.parse / JSON.stringify。 要在Python代码中直接包含一个JavaScript库的缩小版本,请使用以下格式(注意三重引号):

    __pragma__ ('js', '{}', ''' // javascript code ''')

  • Brython的html特定function显然不适用于Transcrypt。 只需使用正常的JavaScript方式。 例子:1)在Brython下,你可能使用'document''id']'来引用一个特定的HTML标记,但是使用Transcrypt你可以使用'document.getElementById('id')(这和你的方式一样它从JavaScript)。 2)你不能用'del nodeName'(bcs是一个brython函数)删除一个节点。 使用像'node.parentNode.removeChild(节点)'的东西。 3)用JavaScript替代所有的brython的DOM函数。 例如class_name = className; text = textContent; html = innerHTML; parent = parentNode; children = childNodes等我猜如果你需要的东西,包含一些旧的浏览器所需的替代品,那么有JavaScript库的。 4)将Brython的set_timeoutreplace为javascripts setTimeout 5)Brython的HTML标签(如BR())需要使用正常的javascript方法replace,并重做所有使用它的操作语法。 要么将纯文本标记注入为innerHTML,要么使用javascript语法创build元素,然后使用正常的javascript DOM语法将它们附加在一起。 我也注意到,对于checkboxbrython使用“如果checkbox='选中':”但Transcrypt很高兴“如果checkbox:”..

  • 上个星期我完成了一个2700线项目,当时Transcrypt没有支持一些小的事情(尽pipe它们很容易用填充符replace),这些是1)str.lower,str.split(str。拆分是存在的,但似乎是JavaScript的拆分,工作不同的python版本,我所依靠的行为),2)轮(这似乎是现在开发版本支持)和3)isinstance didn不适用于str,int和float,只能在字典,列表和集合中使用。 4)我注意到Brython的另一个区别是,如果我拉一个字典的JSON表示,我需要使用'myDict = dict(data)',而brython很满意'myDict = data'。 但是这可能与Brython的json.loads有关,我直接用JSON.parsereplace。 5)也没有专门启用Transcrypts运算符重载(对于全局使用-o切换,或对本地使用__pragma__('opov') ),您不能使用重载格式执行像set操作之类的操作,但需要使用相应的函数。 例如

     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:'来迭代__pragma__('iconv') ,而不启用(cmd行-i或__pragma__('iconv') ,但是你可以避免只用键来启用它()成员例如:

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

总结

  • 我喜欢Brython,因为它很容易和它一起testing你的代码(只是F5)。 它更接近真正的Python,因为大部分的标准库在那里。 我不喜欢在浏览器中包含翻译引擎(编辑:或者可能将其视为python虚拟机),并输出大的javascript大小。 如果我不得不做一些事情(但仍然使用Brython),我会用JavaScript方法来操纵从Brython的DOM(你可以做..),而不是倾斜太多的Brython方法,因为浪费时间移动当我需要改变的时候给另一个译员。

  • 我喜欢Transcrypt,因为输出的JavaScript实际上是“精简而意味着”的,因为你加载浏览器端的唯一东西就是你生成的JavaScript代码,它的大小与Python代码相似。 也因为它支持源地图,因为它给了我一个控制输出的JavaScript的措施。 使用它教会了我相当多的优化。

希望能帮助某人看到哪些对他们的特定项目有好处。

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

这个页面评估了三位候选人。 Brython成为明显的赢家。

尽pipe“帮助”解释说SO对这类问题不好,但在这种情况下似乎可以有一个简洁的答案。

也许人们太仓促了?

首先我是Brython提交者。 尽pipe如此,为了客观评估,我会尽可能保持公正。

我最后一次使用它Skulpt不支持像生成器expression式的function。 Brython和PyPy.js是这样做的,所以在function级别恕我直言,后来是优越的。

Brython(目前)仍在进行中。 一些模块不能被导入(例如xml.ElementTree )。 不过,由于我们正在努力运行整个CPythontesting套件,尽pipe实现了与标准的完全兼容(至less在合理的情况下),这种情况正在开始发生变化。

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

PyPy.js有很多特性,从PyPy(JIT编译,经过很好的testing,…)支持,但我不知道它是否适合在浏览器中运行。 随着项目的发展,这可能会改变。

TODO:我会试着用可靠的基准来补充我的答案。

我已经使用并致力于skyppt以及pypyjs。 而他们都是三个非常不同的,如果你问我,任何比较都是没有意义的。

这取决于你正在寻找哪些最有意义的东西。

PyPyJS

pypyjs是巨大的这是一个12MB的JavaScript文件,其中包含整个pypy虚拟机。 所以如果你想Python的实现完整性,这是你的宝贝。 它有一个JavaScript的桥梁,工作真的很好,但它不是一个可行的select在python中编写您的JavaScript网站代码。 它会让你import compiler

它是用emscripten构build的,而且在运行pystone基准testing时 CPython 更快

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

Skulpt

是一个教学工具(或随着时间的推移已经演变),它将您的Python编译成一个非常接近仿真cpython编译器的状态机。 它的核心是在JavaScript中的Python编译器的手写实现。 它允许asynchronous执行,它可以让你做到:

 while (True): print "hi" 

不locking浏览器。

Skulpt是唯一支持asynchronous延续的程序,它可以让你暂停python的执行,同时解决一些asynchronous的事情。 做这个工作:

 from time import sleep sleep(1) 

当比较pystone时,Skulpt的速度大约是CPython速度的十分之一。

Brython

我至less知道这一个可能@ olemis朗可以扩大这一个。 但除了Brython是py3和其他py2的明显区别之外。 Brython也是一个翻译。

Brython不运行pystone基准testing,因为time.clock没有实现,因为它正式是一个硬件function。

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

我只是试了一下,虽然这是一个有趣的概念,但由于文档很less,还处于早期阶段。

最后,这将取决于你想要做什么。 我select了Transcrypt之后,因为它更实用,性能更好,也是最近发布/维护的。

这里没有提到的是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基准testing,你可以在这里看到结果:

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