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

时间:2015-05-10 19:08:35

标签: python browser brython skulpt transcrypt

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

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

请注意:这不是建议或意见的请求。我正在寻找能够为受过教育的选择提供信息的客观事实。

8 个答案:

答案 0 :(得分:50)

这里有关于Brython vs Transcrypt的一些信息(2016年7月,因为Transcrypt被OP作为这个问题的一个选项添加),几个月前开始与Brython一起开始项目并转移到Transcrypt(上周完成了移动)。我喜欢Brython和Transcrypt,可以看到它们的用途。

对于刚刚接触过这种情况的人来说,Brython和Transcrypt都会对此感到沮丧。 python输入到javascript(编辑:也许最好将Brython视为浏览器的Python实现,因为它不会生成独立的javascript)。两者都需要Python 3语法。 Brython包含大量的Python标准库,其中一些用于处理与Web相关的事情,而Transcrypt在很大程度上避免了这种情况,并建议使用Javascript库。

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

另一方面,

TranscryptGithub)作为python 3 package分发,您可以手动使用,或挂钩到您的工具链,以便提前将python编译为javascript。所以使用Transcrypt,你在python中编写,对python运行transcrypt,它会发出你可以链接到项目中的javascript。它更像传统的编译器,因为它提供了对输出的一些控制。例如,您可以选择编译为ES6或ES5,或者要求它输出源图(在调试期间,浏览器会直接将您带到相应的python代码,生成的javascript代码的内容。)Transcrypt&#39 ; javascript输出非常简洁(换句话说,它很漂亮和简洁)。在我的情况下,150kB的python被转换为165kB的无限制的ES5 javascript。通过比较,我的项目的Brython版本在转换后使用了大约800Kb。

然而,获得Transcrypts简洁的好处,需要阅读一些文档(实际上只是一点点)。例如,使用Transcrypt,Python的真实性'对于像dict这样的数据结构,默认情况下不启用set和list,并且由于与类型检查相关的潜在性能问题而不鼓励全局启用它。为清楚起见:在CPython下,空字典,集合或列表的真值为False,而在Javascript中它被认为是真的' ..示例:

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很难做到(虽然它在技术上是可行的,但是使用{{ 3}}并单击javascript按钮以查看输出)。我这样做并链接到project.html生成的javascript但由于某种原因它没有工作。此外,我发现很难理解来自Brython的错误消息,因此我不知道在此步骤失败后从哪里开始。此外,输出代码的大尺寸和brython引擎的大小开始让我烦恼。所以我决定仔细看看Transcrypt,起初看起来更高档,因为我更喜欢愚蠢的说明,告诉我如何立即开始(这些已经添加)。

安装Python3.5后设置它的主要原因是:

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

    的主要问题

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

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

      __pragma__ ('js', '{}', '''
      // javascript code
      ''')
      
    • Brython的html特定功能显然不适用于Transcrypt。只需使用正常的JavaScript方式。示例:1)在Brython下,您可能使用'文档[' id']'引用了特定的HTML标记,但是使用Transcrypt,您可以使用' document.getElementById(' id')(这与你从javascript中执行的方式相同)。 2)您无法删除带有节点名称'的节点。 (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方式替换,以及重做你使用它的任何地方' s< ; = dom操作语法。将纯文本标记注入innerHTML或使用javascript语法创建元素,然后使用普通的javascript DOM语法附加它们。我还注意到,对于复选框,brython使用"如果checkbox ='选中':"但Transcrypt很满意"如果复选框:" ..

    • 上周我完成了一个2700线项目,当时Transcrypt没有支持一些小的东西(虽然它们很容易用填充物代替),这些都是1)str。 lower,str.split(str.split存在,但似乎是javascript拆分,它与python版本的工作方式不同,我依赖的行为),2)round(这似乎在dev中支持现在版本)和3)isinstance没有在str,int和float上工作,只在dict,list和set上工作。 4)与我注意到的Brython的另一个区别是,如果我输入一个dict的JSON表示,我需要使用' myDict = dict(data)',而brython对&#39感到满意; myDict =数据'。但这可能与Brython的json.loads中的某些内容有关,我直接用JSON.parse替换了它。 5)也没有专门启用Transcrypts运算符重载(使用-o开关表示全局,或__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)另外,默认情况下,你不能在dict中使用' for i来迭代dicts:',而不启用它(cmd行-i或__pragma__('iconv'),但你可以避免必须通过使用keys()成员启用它,例如:

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

    总结

    • 我喜欢Brython,因为它很容易使用它并测试你的代码(只需F5)。它接近真正的python,因为大多数标准库都在那里。我不喜欢在浏览器中包含transilation引擎(编辑:或者可能将其视为python VM)和大输出的javascript大小。如果我必须做的事情(但仍然使用Brython),我会使用javascript方法来操作brython中的DOM(你可以这样做......),而不是过多地依赖于brython方法,因为浪费了时间当我的需求发生变化时,转向另一个转发器。

    • 我喜欢Transcrypt,因为输出的javascript真的很精简并且意味着'并且因为您加载浏览器端的唯一事情是您生成的javascript代码,其大小与您的python代码类似。此外,因为它支持源图,因为它给了我一个控制输出的JavaScript的措施。使用它教会了我很多关于优化的知识。

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

答案 1 :(得分:12)

我已经使用并致力于skulpt和pypyjs。他们三个非常不同,如果你问我,任何比较都没有实际意义。

这取决于你所寻找的最有意义的东西。

PyPyJS

pypyjs很大,它是一个包含整个pypy虚拟机的12MB javascript文件。所以如果你想让python实现完整性,这就是你的宝贝。它有一个非常好的javascript桥,但它不是一个在python中编写你的javascript网站代码的可行选项。但是它会让你import compiler

它是使用emscripten构建的,并且在运行pystone基准测试时更快然后是CPython。

我简短地谈了pypyjs here是幻灯片。

Skulpt

是一种教学工具(或者随着时间的推移已经演变成了这种工具),它将你的python编译成一个非常接近模仿cpython编译器的状态机。在它的核心,它是javascript中python编译器的手写实现。它允许执行异步执行:

while (True):
    print "hi"

不锁定浏览器。

Skulpt是唯一支持异步延续的方法,它允许你暂停python的执行,同时解决一些异步事件的发生。做这项工作:

from time import sleep
sleep(1)

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

Brython

我至少知道这个可能@ olemis-lang可以扩展这一个。但旁边明显的区别是Brython是py3而其他人是py2。 Brython也是一个转换器。

Brython没有运行pystone基准测试,因为time.clock没有实现,因为官方它是一个硬件功能。

答案 2 :(得分:10)

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

此页面对三位候选人进行了基准测试。 Brython成为明显的赢家。

尽管提供了帮助'解释S.O.对于这类问题并不好,似乎在这种情况下可以得到一个简明的答案。

也许人们太仓促了?

答案 3 :(得分:6)

首先,我是一个Brython提交者。尽管如此,为了做出客观的评估,我会尽量保持公正。

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

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

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

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

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

答案 4 :(得分:5)

这里没有提到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=en#!topic/brython/20hAC9L3ayE

答案 5 :(得分:4)

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

我刚试过它,虽然它是一个有趣的概念,但由于文档很少,它仍处于早期阶段。

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

答案 6 :(得分:3)

Running Python in the Browser是一篇非常不错且最新的文章(截至2019年),比较了Brython,Skulpt,PyPy.js,Transcrypt,Pyodide和Batavia。我强烈建议阅读。

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

enter image description here

enter image description here

答案 7 :(得分:2)

这是一次更新的会议,它比较了当前市场上所有可用的选项:

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

发言人是Russell Keith-Magee,他是该地区著名的开发商。