Javascript 中的JS库Brython 介绍指南

Posted by cl9000 on June 07, 2021

创造力是自律与童心的结合体。——<罗伯特·格林>

介绍

在开发 Web 应用程序时 - 我们通常使用多种技术和语言。后端可以很容易地用 Java(Spring Boot)、Python(Django 或 Flask)或 JavaScript (Node.js) 构建,但前端更常使用 JavaScript(React、Angular 等)构建。有时,我们甚至采用混合方法让服务器端呈现页面,并在 React 等前端框架中完成最后的修饰。

多年来,鉴于其在 Web 上的流行——JavaScript 社区扩展了原始功能以启用 JavaScript 驱动的后端,包括前端。在 JavaScript 中编写 Web 应用程序的最常见方法是使用MEAN堆栈。一个 MongoDB 数据库,Node.jsExpress.js 作为后端,Angular(或者最近的 React)作为前端。

但是,如果您真的更喜欢使用 Python 开发您的应用程序呢?虽然严格专注于一种编程语言是不可取的 - 语言是工具,而专注于一种工具会让你不那么灵活 - 单语言应用程序仍有空间。

Brython 可能是解决方案! 它是一个 JavaScript 库,可让您在浏览器中运行 Python 代码。

你可能已经猜到了,Brython 是 Browser Python 的缩写。

顾名思义,Brython 的主要目标是取代 JavaScript 并推动 Python 作为 Web 浏览器的主要脚本语言,适用于您的应用程序:

1
2
3
4
5
6
7
8
9
10
11
<html>
<head>
<script src="/brython.js"></script>
</head>
<body onload="brython()">
<script type="text/python">
import browser
browser.document <= "Hello world!"
</script>
</body>
</html>

<script> 通常不支持的 text/python 类型可以解释的 Python ,我们已经写了代码。在这里,我们向 browser.document 打印了一条 Hello World消息,这类似于 JavaScriptdocument.

在本 Brython 入门指南中- 我们将了解如何安装 Brython、如何初始化 Brython 项目、如何设置页面样式,并将其与一些替代方案进行比较。

如何安装 Brython

利用内容分发网络

实际上,安装 Brython 最方便的方法可能是根本不安装它。如果你不需要在本地安装它,只需要在静态网页上加载它来添加一些动态功能,你应该考虑简单地导入一个外部资源。
其思想是将 brython.js 库加载到 HTML 页面的 <head> 部分。这样,客户端将下载库的同时 HTML 页面加载到他们的 PC 上。

为了实现这一行为,我们将从托管最新稳定版 Brython 在线的一些 cdn (内容分发网络)中加载我们的库。

基本上,内容交付网络是一组托管一些数据(代码、视频内容、图像…)的分布式服务器。这些类型的网络非常可靠,几乎没有停机时间。这使它们成为托管代码库的理想选择。

有几个cdn可供选择,但是,三个受欢迎的是:

1
2
3
4
5
6
7
8
9
10
11
12
<!-- Option 1 : jsDelivr CDN -->
<script src="https://cdn.jsdelivr.net/npm/brython@3.9.1/brython.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/brython@3.9.1/brython_stdlib.js"></script>

<!-- Option 2: CloudFlare CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.1/brython.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.1/brython_stdlib.min.js"></script>

<!-- Option 3: GitHub as the CDN -->
<!-- Choose this option if you want to use the latest developement version -->
<script src="https://raw.githack.com/brython-dev/brython/master/www/src/brython.js"></script>
<script src="https://raw.githack.com/brython-dev/brython/master/www/src/brython_stdlib.js"></script>

通过 Pip 安装 Brython

如果你想要更灵活的 Brython,你可以本地安装:

1
2
3
4
5
6
7
8
9
10
11
$ pip3 install brython

验证 Brython 是否已经成功安装:
$ pip show brython
// Name: brython
// Version: 3.9.2
// Summary: Brython is an implementation of Python 3 running in the browser
// Home-page: http://brython.info
// Author: Pierre Quentel
// Author-email: quentel.pierre@orange.fr
// License: BSD

如何初始化Brython项目

安装 Brython 之后,下一步显然是创建一个简单的项目来测试它的功能。要创建项目,请创建一个新文件夹并移动到它:

1
2
$ mkdir brython-project
$ cd brython-project

现在可以运行以下命令初始化 Brython 项目:

1
brython-cli --install

这将创建并初始化一个 Brython 项目,包括启动项目目录和文件层次结构:

1
2
3
4
5
6
7
brython-project
| brython.js
| brython_stdlib.js
| demo.html
| index.html
| README.md
| unicode.txt

首先,让我们解释一下所有这些文件的用途:

  • Brython .js - Brython核心引擎,它包含了最常用的模块,如browser, browser.html, javascript…如果我们选择不在本地安装Brython,该文件将使用<script>标记包含在HTML页面中。
  • brython_stdlib.js - 包含 Brython 支持的 Python标准库中的所有包和模块。
  • demo.html - 一个运行Brython的简单HTML页面,展示了一些有趣的用例和如何利用 Brython 修改静态HTML页面的示例。
  • index.html - 一个简单的 Hello World HTML页面。

只使用一个简单的 web 浏览器就可以打开 demo.html ,但是这种方法有其局限性,因此建议首先启动本地主机服务器

如果您还没有http安装该模块,您也可以通过pip以下方式安装它:

1
$ pip3 install http

安装后,我们可以启动服务器:

1
$ python3 -m http.server

现在,您应该在 (默认) 上启动本地主机 port 8000,并且您应该能够 demo.html 通过导航到您选择的 Web 浏览器的地址栏中的http://localhost:8000/demo.html(或http://0.0.0.0:8000/demo.html)来访问该页面。

如果端口 8000 当前被其他进程使用,则您必须定义另一个要使用的端口(例如 8080):

1
$ python3 -m http.server 8080

要创建一个能够运行 Python 的新 HTML 页面,您只需要在文件部分导入brython.js和文件。然后,您可以继续在 HTML 文件本身中编写 Python:brython_stdlib.jshead

1
2
<script src="brython.js"></script>
<script src="brython_stdlib.js.js"></script>

Brython 的工作原理

Brython 通过将 Python 代码转换为 JavaScript,使我们能够在浏览器中编写和运行 Python 代码。这段代码将能够在所有支持 JavaScript 的现代浏览器中运行,因为 Brython有意避免使用新的、不受支持的语法生成 JavaScript
https://scotch.io/tutorials/javascript-transpilers-what-they-are-why-we-need-them

您可以将转译视为编译的一个子集。
编译过程通常将用某种高级编程语言(例如C)编写的源代码转换成某种低级语言(例如机器代码)。
另一方面,transpilation 是将一种高级语言转换为另一种高级语言(例如 Python 到 JavaScript)的过程。

Brython 中的转译发生在加载 HTML 页面的同时。在这里,我们在 HTML 文档 brython()body 标签中调用函数:

1
<body onload="brython()">

brython() 函数执行编写在<script type="text/python">HTML 文档标签中的 Python 代码的转译。所有 Python 代码都必须用<script type="text/python">标记包围:

1
2
3
<script type="text/python">
<!-- Python code -->
</script>

或者,我们可以通过使用以下命令将外部 Python 代码加载到 HTML 文档中:

1
<script type="text/python" src="test.py"></script>

所有现代 Web 浏览器都支持 JavaScript 作为主要脚本语言,但不支持 Python。因此,所有 Python 代码都需要转换为 JavaScript,然后在加载 HTML 页面所需的时间内运行。

首先,brython()函数通过检查所有类型为 的脚本来搜索 HTML 页面中的所有 Python 代码 text/python,然后将所有代码转换为 JavaScript

这种转换的结果是 JavaScript 代码的简单字符串表示。该字符串必须在浏览器中作为 JavaScript 代码运行。

Brython 使用 JavaScripteval()函数来运行所有翻译后的代码。或者,它可以利用 JavaScript 命令 new Function(function_name, source)(module) 在某些浏览器上运行代码。

这不是运行 JavaScript 的首选方式。使用eval()可能很危险,因为它可能会将应用程序暴露给潜在的恶意第三方代码。此外,eval()与替代品相比,速度相当慢。

如果 Python 代码通过 加载到 HTML 文档中<script type="text/python" src="url">,Brython 将执行 Ajax 调用以获取加载文件的内容。该代码被转换为 JavaScript 并以与上述相同的方式执行。

使用 Brython - 示例

现在,让我们回顾一些简单的例子,以便您了解 Brython 的工作原理及其功能:

Heoll Word

1
2
3
4
5
6
7
8
9
10
11
<html>
<head>
<script src="/brython.js"></script>
</head>
<body onload="brython()">
<script type="text/python">
import browser
browser.document <= "Hello world!"
</script>
</body>
</html>

我们将重点关注标签之间的 Python 代码:

  • import browserbrowser 包加载到脚本中。它是对所有 Brython 特定名称和模块进行分组的包,主要用于表示 JavaScript 中使用的 DOM 元素和事件。
  • browser.document 是表示当前显示的 HTML 文档的对象。
  • browser.document <= "Hello world!" - 我们使用 <= 符号而不是 = . 的 document “接收”包含字符串的新元素 Hello world!。另一种方法是使用以下语法:browser.document.attach("Hello world!").

在客户端,一旦呈现此代码 - 它会导致:

1
2
3
4
5
6
7
8
<html>
<head>
<script src="/brython.js"></script>
</head>
<body onload="brython()">
Hello world!
</body>
</html>

添加元素和属性

让我们修改前面的示例并为其添加一些段落和文本格式。该browser接口为我们提供了html模块,该模块公开了 HTML 标记,我们可以使用这些标记从 Python 代码动态创建 HTML 结构。创建对象的语法是:

1
browser.html.TAG("content", [attributes])

哪些输出:

1
<TAG [attributes]>content</TAG>
  • browser.html.H2("Hello world!")Hello world<h2>标签包裹字符串。
  • browser.html.A("link", href="stackabuse.com") 创建一个 <a href="stackabuse.com"> 标签。

使用这种语法也可以嵌套,只需 html.element 在另一个元素中包含一个。让我们在页面中添加一些元素:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
<head>
<script src="/brython.js"></script>
</head>
<body onload="brython()">
<script type="text/python">
import browser

title = browser.html.H2("Hello world!")

bold = browser.html.B("bold text")
url = browser.html.A("link", href="stackabuse.com")
paragraph = browser.html.P("This is a paragraph. This is " + bold + ", and this is a " + url)

browser.document <= title
browser.document <= paragraph
</script>
</body>
</html>

或者, url = browser.html.A("link", href="stackabuse.com")您可以不使用任何参数创建一个对象,而不是创建一个带有参数的对象并构建它:

1
2
3
4
5
6
7
8
9
# Creating an <a></a> tag
url = browser.html.A()

# Adding content between created tags
# <a>Url Text</a>
url <= "Url Text"
# Adding href attribute
# <a href="cl9000.github.io">Url Text</a>
url.href = "cl9000.github.io"

当我们完成 Python 代码并在浏览器中打开页面时 - 生成的 HTML 页面应如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
<html>
<head>
<script src="/brython.js"></script>
</head>
<body onload="brython()">
<h2>Hello world!</h2>
<p>
This is a paragraph. This is <b>bold text</b>, and this is a
<a href="stackabuse.com">link</a>.
</p>
</body>
</html>

我们有一个 <p> 元素,在其中我们使用了预先构造的 <b>and<a> 元素。

使用 Brython 创建表格

可以使用与我们迄今为止一直应用的逻辑大致相同的逻辑来创建表:

1
table = browser.html.TABLE()

现在,让我们用一些模拟数据创建几行并将它们添加到 table

1
2
3
4
5
6
7
8
9
10
11
12
13
# Creating the row
row = browser.html.TR()
# Adding header cells
row <= browser.html.TH("Header1")
row <= browser.html.TH("Header2")
# Appending the row to the table
table <= row

# Adding a first row
row = browser.html.TR()
row <= browser.html.TD("Data 1")
row <= browser.html.TD("Data 2")
table <= row

最后,我们选择 <div id="table-zone">在 HTML 页面上创建的银行元素中显示表格:

1
2
tableZone = browser.document["table-zone"] 
tableZone <= table

这会在我们的页面上生成一个 HTML 表格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="table-zone">
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</tbody>
</table>
</div>

向现有元素添加样式

让我们为 <div id="table-zone">table 元素添加一些样式:

1
2
3
4
5
6
7
8
9
10
11
tableZone.style = {
"background-color": "#dedfdd",
"width": "50%",
"min-height": "100px",
"margin": "auto"
}

table.style = {
"border": "1px solid #333",
"margin": "auto"
}

这将导致修改后的 HTML 标签style添加属性:

1
2
3
<div id="table-zone" style="background-color: rgb(222, 223, 221); width: 50%; min-height: 100px; margin: auto;">

<table style="border: 1px solid rgb(51, 51, 51); margin: auto;">

绑定操作和从元素读取内容

网页不仅用于显示数据 - 它们还用于捕获数据。表单是我们提示用户发送数据的最基本方式之一。让我们在 Brython 中使用 FORM() 函数以及其他 HTML 元素(例如 INPUT()LABEL())创建一个表单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Create a <div id="form-div"> element as a container for a new form
formDiv = browser.html.DIV(id="form-div")
# Create a <form> element
form = browser.html.FORM()

# Create the <input type="text"> field wit the label and add it to the form
input = browser.html.INPUT()
input.type = "text"
input.id = "input-name"
# Add label and to the form
form <= browser.html.LABEL("Enter your name: ") + input

# Create the submit button and add it to the form
button = browser.html.INPUT()
button.type = "button"
button.value = "Submit"
button.id = "submit-button"
form <= button

# Add form to the container <div> element
formDiv <= form
# Add the <h4 id="form-response"> to show the value from the form
formDiv <= browser.html.H4("Your name is: ", id="form-response")
# Display the div element containing form on the page
browser.document <= formDiv

不做任何事情的表单不是很有用。我们也可以在 Brython 中使用自定义函数。让我们创建一个clicksubmit按钮上调用的 Python 函数。它会提醒用户按钮已被点击并更新 <h4 id="form-response">元素的值:

1
2
3
4
5
6
7
def onSubmit(ev):
# Get the value of the <input id="input-name"> field
name = browser.document["input-name"].value
# Append the stored value to the content in the <h4 id="form-response"> tag
browser.document["form-response"] <= name
# Alert the user that the button has been clicked
browser.alert("The Submit Button is Clicked")

最后,我们将click事件 submit-button 与创建的onSubmit()函数绑定,以便我们在按钮单击时获得所需的行为:

1
browser.document["submit-button"].bind("click", onSubmit)

结论

如果您正在寻找 JavaScript 作为 Web 脚本语言的替代方案,并且不太关心性能,那么 Brython 可能是一个不错的解决方案。

它平衡了执行速度和加载库所需的多余内存使用之间不可避免的权衡,使其成为在浏览器中运行 Python 的最佳解决方案之一。

另一方面,Brython 没有庞大的社区,也没有被广泛接受或使用。学习资源非常有限,您将仅限于主要是官方文档,而没有许多现实世界的大型项目可以寻求指导。

最终,主要问题是是否值得完全替换 JavaScript。与用 JavaScript 编写的完全相同的项目相比,即使是小型 Brython 项目的执行速度也可能慢 2 倍。与 Brython 不同,JavaScript 拥有庞大的开发者社区、海量资源和展示其全部潜力的真实项目。

让我们不要忘记所有的 JavaScript 框架,它们是 JavaScript 流行的支柱。如果没有他们的帮助,JavaScript 将只是另一种脚本语言,它为我们提供了动态更改静态 HTML 页面内容的能力。例如,想象一下用纯 JavaScript 编写复杂的服务器端逻辑。即使那是可行的,这肯定不会是一个非常愉快的经历。

不幸的是,Brython 没有为其开发框架,因此您只能使用纯 Python 代码,这对于除简单用例之外的任何其他内容都不合理。您可能无法使用 Brython 创建一些复杂的单页 Web 应用程序,而您可以使用 JavaScript 和 Angular。Brython 是一个很好的工具,对于那些只想使用 Python 进行服务器端和客户端编程的开发人员来说,但它可能离取代 JavaScript 还有很长的路要走

参考

关注【公众号】,了解更多。



支付宝打赏 微信打赏

赞赏一下 坚持原创技术分享,您的支持将鼓励我继续创作!