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

问题描述 投票:58回答:7

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

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

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

python browser brython skulpt transcrypt
7个回答
53
投票

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

对于那些不熟悉的人,Brython和Transcrypt都将'transile'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的javascript输出非常简洁(或换句话说,它很漂亮和简洁)。在我的情况下,150kB的python被转换为165kB的无限制的ES5 javascript。通过比较,我的项目的Brython版本在转换后使用了大约800Kb。

但是,获得Transcrypts简洁的好处,需要阅读一些文档(实际上只是一点点)。例如,使用Transcrypt,默认情况下不启用Python对dict,set和list等数据结构的“真实性”,并且由于与类型检查相关的潜在性能问题而不鼓励全局启用它。为清楚起见:在CPython下,空字典,集合或列表的真值为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很难做到(尽管技术上可行,使用online editor并点击javascript按钮查看输出)。我这样做并链接到project.html生成的javascript但由于某种原因它不起作用。此外,我发现很难理解来自Brython的错误消息,因此我不知道在此步骤失败后从哪里开始。此外,输出代码的大尺寸和brython引擎的大小开始让我烦恼。所以我决定仔细看看Transcrypt,起初看起来更高档,因为我更喜欢愚蠢的说明,告诉我如何立即开始(这些已被添加)。

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

  1. 使用venv(它就像一个新的内置版本的virtualenv,每个项目使用更少的空间)来设置python3.5项目文件夹(只需输入:python3.5 -m venv foldername - workaround for ubuntu with package issues for 3.5)。这使得'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。

主要问题正在蔓延

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

  • 你需要用javascript libs替换brython或python标准库。例如,'import json'由Brython提供,但在Transcrypt下你可以使用javascript lib或直接在你的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很满意“如果复选框:”..
  • 我上周完成了一个2700线项目,当时Transcrypt没有支持一些小的东西(虽然它们很容易用填充物代替),这些是1)str.lower,str.split(str。 split存在,但似乎是javascript拆分,它与python版本的工作方式不同,我依赖的行为),2)round(这似乎现在支持dev版本)和3)isinstance didn只在dict,list和set上使用str,int和float。 4)与我注意到的Brython的另一个区别是,如果我输入一个dict的JSON表示,我需要使用'myDict = dict(data)',而brython对'myDict = data'感到满意。但这可能与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)此外,你不能默认使用'for i in dict:'来迭代dicts,而不启用它(cmd行-i或__pragma__('iconv'),但你可以避免只使用keys()成员启用它,例如:

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

总结一下

  • 我喜欢Brython,因为它很容易使用它并测试你的代码(只需F5)。它更接近真正的python,因为大多数标准的lib都在那里。我不喜欢在浏览器中包含transilation引擎(编辑:或者可能将其视为python VM)和大输出的javascript大小。如果我必须做的事情(但仍然使用Brython),我会使用javascript方法来操作brython中的DOM(你可以这样做......),而不是过多地依赖于brython方法,因为浪费了时间当我的需求改变时,另一个转换器。
  • 我喜欢Transcrypt,因为输出的javascript真的是'精益和卑鄙',因为你加载浏览器的唯一一件事是你生成的javascript代码,它的大小与你的python代码相似。此外,因为它支持源图,因为它给了我一个控制输出的JavaScript的措施。使用它教会了我很多关于优化的知识。

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


12
投票

我曾经使用并致力于雕塑以及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速度的十分之一左右运行。

英国人

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

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


10
投票

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

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

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

也许人们太仓促了?


6
投票

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

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

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

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

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

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


5
投票

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

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


4
投票

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

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

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


2
投票

这是一个更新的会议,比较市场上现有的所有可用选项:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.