如何在前端运行 Python 程序
在传统的 Web 开发中,Python 通常更多地被用作服务器端语言(如 Django、Flask 等),而在浏览器端(前端)通常使用 JavaScript 来操作 DOM、进行事件处理等。不过,随着 WebAssembly 技术的发展和一些 Python-to-JavaScript 转译方案的出现,我们已经可以在前端直接运行(或间接编译)Python 代码。
下面将详细介绍在前端运行 Python 程序的多种主要方式、它们的优点和局限性,并附带一些示例或基本使用思路。
一、直接在浏览器运行 Python:基于 WebAssembly 的 Pyodide
1. 什么是 Pyodide
Pyodide 是基于 WebAssembly 的一个完整 Python 解释器项目,它将 CPython(Python 的官方解释器)编译成了可以在浏览器环境(或者其它 WebAssembly 运行环境)里执行的版本。换句话说,你不需要安装任何插件,只要浏览器支持 WebAssembly,你就可以在前端环境里运行几乎完整的 Python。
2. Pyodide 的主要特点
- 兼容性好:几乎完整移植了 CPython,包括标准库和部分第三方库的支持(如 NumPy、Pandas 等)。
- 易集成:官方提供了一个
pyodide.js
(或pyodide.mjs
),前端只要将其引入即可使用。 - WebAssembly 性能:相较于纯 JavaScript 解释 Python 的方案,Pyodide 的性能更好。
3. 如何使用 Pyodide
-
引入 pyodide.js
从官方的 CDN 或者本地托管,引入 Pyodide 脚本:<script src="https://cdn.jsdelivr.net/pyodide/v0.23.4/full/pyodide.js"></script>
提示:版本号可能会不断更新,可以去 Pyodide Releases 查看最新版本。
-
初始化 Pyodide 环境
<script> async function initPyodide() { // 加载 Pyodide let pyodide = await loadPyodide(); // 在这里就可以使用 pyodide.runPython 执行 Python 代码了 let result = pyodide.runPython(\` import sys sys.version \`); console.log("Python version:", result); } initPyodide(); </script>
-
执行 Python 代码
pyodide.runPython(code)
可以直接执行一段 Python 代码字符串,并返回最后一行表达式的值(如果有)。pyodide.globals
可以获取当前 Python 解释器中全局作用域的变量。- 除了执行简单的脚本外,还可以加载第三方库(部分纯 Python 库已经预编译到 Pyodide 里)。
示例:
<script> async function initPyodide() { let pyodide = await loadPyodide(); // 安装 / 加载一些包 await pyodide.loadPackage("micropip"); // micropip 可以安装更多的 Python 包,但需要兼容 WASM,如 pyodide.org 中提到的包 // 运行简单的 Python 代码 let code = \` import math def compute_circle_area(r): return math.pi * (r ** 2) area = compute_circle_area(5) \`; pyodide.runPython(code); let area = pyodide.globals.get("area"); console.log("Circle area:", area); } initPyodide(); </script>
4. 优缺点
- 优点:
- 几乎完整地支持 Python 生态,能够直接使用很多 Python 包,尤其是科学计算相关。
- 依赖 WebAssembly,高度还原 CPython 功能,运行效率相对其他纯 JS 解释器更高。
- 缺点:
- 体积较大,需要加载编译好的 Python 解释器和相关包,初次加载可能会比较耗时。
- 并非所有 Python 包都能在 Pyodide 中使用,一些依赖本地 C/C++ 扩展的库需要专门移植。
二、Brython:将 Python 作为浏览器脚本语言
1. 什么是 Brython
Brython 是一款用 JavaScript 实现的 Python 解释器,它的目标是让 Python 可以取代前端开发中 JavaScript 的地位。它提供了一个运行时环境,使用纯 JavaScript 解释 Python 语法,并且封装了一系列 DOM 操作、浏览器接口等,使得你可以像写 JavaScript 一样来操作浏览器对象。
2. Brython 的使用
- 引入 Brython
<script src="https://cdn.jsdelivr.net/npm/[email protected]/brython.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/brython_stdlib.js"></script>
- HTML 标记与启动
在<body>
标签中添加onload="brython()"
或者用 JavaScript 的方式在 DOM 加载后初始化 Brython:<body onload="brython()"> ... </body>
- 在
<script type="text/python">
中编写 Python
Brython 允许我们直接在 HTML 文件中使用<script type="text/python">
标签来书写前端 Python 代码,如:
这里<script type="text/python"> from browser import document, alert def greet(ev): alert("Hello from Brython!") document["mybutton"].bind("click", greet) </script>
document["mybutton"]
与 JavaScript 中的document.getElementById("mybutton")
类似。
3. 优缺点
- 优点:
- 使用非常简单,直接
<script type="text/python">
就能写代码。 - 对 DOM 操作进行了一定的封装,可以让 Python 代码操作浏览器 API。
- 代码体积相对 Pyodide 更小(毕竟没有完整移植 CPython)。
- 使用非常简单,直接
- 缺点:
- Brython 并不包含完整的 Python 标准库实现,某些场景下功能有限。
- 由于是纯 JavaScript 解释,需要考虑性能影响,复杂运算性能可能远低于 WebAssembly 方案。
- 一些 Python 第三方库可能无法直接使用,或需要依赖特定的 Polyfill。
三、Transcrypt:Python 转译成 JavaScript
1. 什么是 Transcrypt
Transcrypt 是一个将 Python 代码编译成高质量、可读性较高的 JavaScript 代码的工具。可以在开发阶段用 Python 编写逻辑,然后通过 Transcrypt 将其编译成 JavaScript,最终在浏览器端运行的还是 JavaScript。
2. 工作流程
- 安装 Transcrypt:
pip install transcrypt
- 使用 Transcrypt 编译 Python 文件:
transcrypt -b -m myscript.py
-b
表示在浏览器模式下编译(browser)。-m
表示生成映射文件(source map)。
- 编译完成后,会生成一个
__javascript__
文件夹,里面有myscript.js
以及依赖文件。 - 在 HTML 中引入编译后的 JS 文件:
<script src="__javascript__/myscript.js"></script>
- 这样,就可以在浏览器端使用转换后的 JS 逻辑。
3. 优缺点
- 优点:
- 保持了 Python 语法的开发体验。
- 得到的 JavaScript 体积相对较小,且没有额外的运行时依赖。
- 编译后的速度与 JavaScript 本身类似(毕竟最终产物是 JS)。
- 缺点:
- 并不是在浏览器里直接执行 Python,而是将 Python 转译成 JS,某种程度上要对 Python 语法有一定限制。
- 对于 Python 的某些动态特性和部分库支持不完美。
四、Skulpt、RapydScript 等其他方案
除上述方案外,还有一些项目也能帮助在前端运行(或近似运行)Python:
-
Skulpt
- 纯 JavaScript 实现的 Python 解释器。
- 支持 Python 语法的子集,适用于教学或简单脚本场景。
- 不支持完整标准库。
-
RapydScript
- 一种 Python-like 语法,编译成高效的 JavaScript。
- 更接近于一种独立的语言,兼具 Python 与 JavaScript 的特性。
-
Trinket、Replit 等在线平台
- 通过远程服务器或 WebAssembly 内嵌的方式,在网页里直接运行 Python 代码。
- 适合教学、演示或小型项目试验。
五、适合不同场景的选择建议
-
如果你希望在浏览器端完整运行 Python 并使用科学计算库(如 NumPy、Pandas 等)
- Pyodide 是首选方案,但要注意加载速度、兼容性以及内存使用。
-
如果你想在前端用 Python 语法来操作 DOM,替代部分 JavaScript 功能
- Brython 可以尝试,不过要注意第三方库的支持以及性能。
-
如果你的核心需求仍然是将 Python 逻辑转成最终的 JavaScript
- Transcrypt 可以帮助你在保持 Python 开发体验的同时,得到优化后的纯 JS 代码。
-
如果你是教学或简单的 Python 脚本交互
- Skulpt、Trinket 这类项目或在线平台可以快速上手,但功能相对有限。
六、总结
在浏览器里运行 Python 不再是遥不可及的想法,随着 WebAssembly 的普及和多种 Python-to-JavaScript 解决方案的出现,前端与 Python 生态之间的融合将越来越紧密。选择具体方案时,需要综合考虑:
- 是否需要大量使用 Python 第三方库?
- 对性能与包体积的要求如何?
- 是否需要调用浏览器的 DOM 或 Web API?
- 是否只是教学、实验,还是要应用到生产环境?
无论是直接基于 WebAssembly 的 Pyodide、JavaScript 实现的 Brython,还是把 Python 编译/转译为 JavaScript 的 Transcrypt,都是在不同场景下可选的思路。未来,随着 Web 技术的进一步发展,前端与 Python 的结合也会更容易、更高效。希望以上介绍能帮助你更好地理解和选择前端运行 Python 的最佳方式。