我很高兴看到现在可以在浏览器中编写Python代码了。这些是主要候选人(请添加我可能忽略的任何内容):
但是如何在它们之间进行选择?我可以看到的唯一明显区别是Skulpt基于Python 2,而Brython基于Python 3。
请注意:这不是要求提供建议或意见。我正在寻找客观的事实,以提供有根据的选择。
Answers:
在浏览器中运行Python是一篇非常不错且最新的文章(截至2019年),该文章比较了Brython,Skulpt,PyPy.js,Transcrypt,Pyodide和Batavia。我强烈建议阅读。
在下面的图片中可以看到很好的总结。
以下是有关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请求了。
另一方面,Transcrypt(Github)作为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.
至少有三种方法可以解决此问题:
__pragma__(tconv)
或__pragma__(notconv)
来告诉Transcrypt编译器在本地开启自动转换为类似python的真值的功能。是的,所以我的项目越来越大,我想进行预编译以提高性能,但是发现使用Brython很难做到这一点(尽管从技术上讲是可行的,一种简单的方法是使用在线编辑器并单击javascript按钮以查看输出)。我做到了,并链接到从project.html生成的javascript,但是由于某些原因,它无法正常工作。另外,我发现很难理解来自Brython的错误消息,因此在此步骤失败后我不知道从哪里开始。同样,输出代码的大尺寸和brython引擎的尺寸也开始困扰我。因此,我决定仔细研究一下Transcrypt,它起初似乎是较高的等级,因为我更喜欢笨拙的说明来告诉我如何立即开始使用(这些内容已经添加了)。
在安装Python3.5之后进行设置的主要目的是:
activate
如果您不想每次都键入foldername / bin / python3.5的完整路径,则为当前终端。输入以下内容激活:“源文件夹名称/ bin /激活”__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有一定的控制权。使用它教会了我很多关于优化的知识。
希望可以帮助某人了解其中的哪一项可能对他们的特定项目有利。
我已经使用并致力于skpy和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,因为正式地说,它是硬件功能。
该页面对这三个候选人进行了基准测试。Brython显然是赢家。
尽管“帮助”解释了SO不适用于此类问题,但在这种情况下,简洁的答案似乎是可能的。
也许人们太草率了?
首先,我是Brython的提交者。但是为了进行客观评估我会尽量保持公正。
我上次使用它时,Skulpt不支持生成器表达式之类的功能。Brython和PyPy.js这样做,因此在IMHO的功能级别上,后者要好一些。
Brython(此时)仍在进行中。某些模块无法导入(例如xml.ElementTree)。尽管如此,这种情况开始改变,因为尽管我们实现了与标准的完全兼容性(至少在合理的情况下),但我们正在努力运行整个CPython测试套件。
Brython还支持.vfs.js来加快模块导入。
由于PyPy.js由PyPy提供支持(JIT编译,经过良好测试,...),因此具有许多直接的特征,但是我不确定它是否适合在浏览器中运行。随着项目的发展,这可能会改变。
待办事项:我将尝试用可靠的基准来补充我的答案。
这里没有提到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
由于没有人提到它,所以我认为值得提及Batavia,它实现了用于运行预编译的Python字节码的Python虚拟机。
我只是尝试了一下,尽管它是一个有趣的概念,但由于文档很少,它仍处于早期阶段。
最后,这取决于您要做什么。我看了一下就选择了Transcrypt,因为它更加实用,性能更好,而且也是最近发布/维护的。
这是一次更新的会议,比较了当前市场上所有可用的选项:
https://www.youtube.com/watch?v=2XSeNQyPlTY
演讲者是拉塞尔·基思·马吉(Russell Keith-Magee),他是该地区著名的开发商。