<p>以下是一些关于布莱森vs Transcrypt的信息(2016年7月,因为OP将Transcrypt作为这个问题的选项添加),几个月前与布莱森开始了一个项目,并搬到了Transcrypt(上周完成了搬迁)。我喜欢布莱顿和Transcrypt,能看到它们的用途。</p>
<p>对于新手来说,Brython和Transcrypt都是“transpile”python对javascript的输入(编辑:也许最好将Brython视为“浏览器的python实现”,因为它不生成独立的javascript)。两者都需要Python 3语法。Brython包含大量的Python标准库和一些自己的用于处理与web相关的东西的库,而Transcrypt在很大程度上避免了这一点,并建议使用Javascript库。</p>
<p><a href="http://brython.info/" rel="noreferrer">Brython</a>(<a href="https://github.com/brython-dev/brython" rel="noreferrer">Github</a>)可以在浏览器中进行转换。因此您使用python编写,当页面加载时,brython.js引擎会动态地将其转换为javascript。这真的很方便,而且比你想象的要快得多。但是,您需要在页面中包含的brython.js引擎大约是500Kb。另外,还有导入标准库的问题,Brython通过使用XHR请求获取单独的.js文件来处理这些库。有些lib已经编译到brython.js中,所以不是每个导入都会拉入新文件,但是如果您使用许多导入,事情可能会变慢。然而,这是有办法的。我所做的是检查浏览器开发工具中的“网络”选项卡,查看加载页面时正在拉入哪些文件,然后删除项目在Brython src文件夹副本中未使用的所有文件,并运行Brython附带的脚本(我认为它位于Brython/www/script s/make-VFS.py),该脚本将所有可用的lib编译为一个名为py VFS.js的文件,您还需要从html链接到该文件。通常,它会生成一个巨大的2MB+文件,但如果删除不使用的东西,它可能会非常小。这样做,意味着您只需要输入brython.js、py-VFS.js和您的python代码,而不需要额外的XHR请求。</p>
<p>另一方面,<a href="http://transcrypt.org/" rel="noreferrer">Transcrypt</a>(<a href="https://github.com/qquick/Transcrypt" rel="noreferrer">Github</a>)作为<a href="https://pypi.python.org/pypi/Transcrypt" rel="noreferrer">python 3 package</a>分发,您可以手动使用它,或者挂接到您的工具链中,提前将python编译为javascript。因此,使用Transcrypt,您可以用python编写,对python运行Transcrypt,它会弹出javascript,您可以在项目中链接到它。它更像是一个传统的编译器,因为它提供了对输出的一些控制。例如,您可以选择编译到ES6或ES5,或者要求它输出源映射(在调试期间,让浏览器直接将您带到相应的python代码,插入生成的javascript代码。)Transcrypt的javascript输出非常简洁(或者换句话说,它非常简洁)。在我的例子中,150kB的python被转换为165kB的未统一的ES5 javascript。通过比较,我的项目的Brython版本在转换后使用了大约800Kb。</p>
<p>然而,要获得Transcrypts简洁性的好处,需要阅读一些文档(实际上只是一点)。例如,对于Transcrypt,Python对于dict、set和list等数据结构的“真实性”在默认情况下是不启用的,并且由于与类型检查相关的潜在性能问题,不鼓励全局启用它。为了清楚起见:在CPython下,空的dict、set或list的真值为False,而在Javascript中,它被认为是true。。示例:</p>
<pre><code>myList = []
if myList: # False in CPython bcs it's empty, true in javascript bcs it exists
# do some things.
</code></pre>
<p>至少有三种方法可以解决这个问题:</p>
<ul>
<li>在将python转换为javascript时使用-t标志,例如:$transcrypt-tpython.py(不推荐,但除非在性能敏感代码的内部循环中多次检查其真实性,否则可能不是问题)</li>
<li>在代码中使用<code>__pragma__(tconv)</code>或<code>__pragma__(notconv)</code>告诉transcrypt编译器在本地打开自动转换为类似python的真值。</li>
<li>而不是检查真实值,av只需检查len(myList)>;0,就可以彻底解决问题。。。也许这对大多数情况都没问题,做这项工作对我来说很简单。</li>
</ul>
<p>是的,所以我的项目变得越来越大,我想通过预编译来提高性能,但发现使用Brython很难做到这一点(尽管从技术上讲这是可能的,一个简单的方法是使用<a href="http://brython.info/tests/editor.html?lang=en" rel="noreferrer">online editor</a>并单击javascript按钮来查看输出)。我这样做了,并链接到从project.html生成的javascript,但是由于某种原因它没有工作。另外,我发现很难理解来自Brython的错误消息,所以我不知道在这个步骤失败后从哪里开始。而且,输出代码的大尺寸和brython引擎的大尺寸也开始困扰我。所以我决定仔细研究一下Transcrypt,它起初的成绩似乎更高,因为我更喜欢一些简单的说明,告诉我如何立即开始(这些已经添加)。</p>
<p>在安装Python3.5之后设置它的主要内容是:</p>
<ol>
<li>使用venv(它就像一个新的内置版本的virtualenv,为每个项目使用更少的空间)来设置python3.5项目文件夹(只需键入:python3.5-m venv foldername-<a href="https://gist.github.com/denilsonsa/21e50a357f2d4920091e" rel="noreferrer">workaround for ubuntu with package issues for 3.5</a>)。这使得“foldername”与bin子文件夹一起出现。</li>
<li>使用pip('foldername/bin/pip Install Transcrypt')安装Transcrypt python包,然后将其安装到foldername/lib/python3.5/site-packages/Transcrypt。</li>
<li><code>activate</code>如果您不想每次都键入foldername/bin/python3.5的完整路径,则为当前终端。通过键入“source foldername/bin/Activate”激活</li>
<li>开始编写代码并将其编译为javascript进行测试。从您编写代码的文件夹中编译。例如,我使用foldername/www/project。因此,将CD放入该文件夹并运行:“transcrypt-b your_python_script.py”。将输出放在名为<code>__javascript__</code>的子文件夹中。然后,您可以从html链接到输出的javascript。</li>
</ol>
<p><strong>主要问题</p>
<p>我的需求很简单,所以你的里程数可能会有所不同。</p>
<ul>
<li><p>您需要用javascript库替换brython或python标准库。
例如,Brython提供了import json,但是在Transcrypt下,可以使用javascript库,或者直接在Python代码中使用json.parse/json.stringify。要在python代码中直接包含javascript库的缩小版本,请使用以下格式(注意三个引号):</p>
<pre><code>__pragma__ ('js', '{}', '''
// javascript code
''')
</code></pre></li>
<li><p>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函数。e、 g.class_name=className;text=textContent;html=innerHTML;parent=parentNode;childrends=childNodes等等。我想如果你需要一些包含一些旧浏览器所需的替代方案的东西,那么就有javascript库。4) Brython的set_timeout替换为javascript s setTimeout 5)Brython的html标记(如BR()需要使用普通的javascript方法替换)以及重做任何使用它的<;=dom操作语法的地方。要么将纯文本标记作为innerHTML注入,要么使用javascript语法生成元素,然后使用普通javascript DOM语法附加它们。我还注意到,对于复选框,brython使用“if checkbox=”checked“:”但是Transcrypt对“if checkbox:”很满意。。</p></li>
<li><p>上周我完成了一个2700生产线的项目,那时Transcrypt不支持一些小事情(尽管它们很容易重播)e with filler),这些是1)str.lower,str.split(str.split是存在的,但似乎是javascript拆分,它的工作方式与python版本不同,我所依赖的python版本的行为),2)round(现在开发版本似乎支持这种方式)和3)isinstance不在str、in t和float上工作,只在dict、list和set上工作。4) 与Brython的另一个不同之处在于,如果我拉入dict的JSON表示,我需要使用'myDict=dict(data)',而Brython对'myDict=data'很满意。但这可能与Brython的json.loads中的某些内容有关,我直接将其替换为json.parse。5) 另外,如果没有特别启用Transcrypts运算符重载(使用-o开关进行全局重载,或使用<code>__pragma__('opov')</code>进行本地重载),则不能使用重载格式执行set操作等操作,而是需要使用相应的函数。E、 g</p>
<pre><code>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
</code></pre></li>
</ul>
<p>6)另外,默认情况下,如果不启用(cmd line-i或<code>__pragma__('iconv')</code>),您也不能使用“for i in dict:”来迭代dict,但是您可以通过仅使用keys()成员来避免启用它,例如:</p>
<pre><code>for key, value in dict.items():
# do things for each key and value..
</code></pre>
<p><strong>总结</strong></p>
<ul>
<li><p>我喜欢Brython,因为使用它和测试代码(只需F5)都很容易。它更接近于真正的python,因为大多数标准库都在那里。我不喜欢在浏览器中包含transpilation引擎(Edit:Or-one-may-view-it-as-python VM)和输出的大javascript大小。如果我不得不重新做一些事情(但仍然使用Brython),我会使用javascript方法来操作Brython中的DOM(您可以这样做…),而不是太依赖Brython方法,因为当我的需求改变时,将浪费时间转移到另一个transpiler。</p></li>
<li><p>我喜欢Transcrypt,因为输出的javascript是真正的“精干和中庸”的,并且因为您在浏览器端加载的唯一东西是生成的javascript代码,它的大小与您的python代码相似。还因为它支持sourcemaps,而且它给了我对输出的javascript的控制能力。使用它教会了我很多关于优化的知识。</p></li>
</ul>
<p>希望这有助于人们了解哪些可能对他们的特定项目有好处。</p>