PyScript:让 Python 直接跑在浏览器里的开源平台
阅读时间: 大约 11 分钟
PyScript:让 Python 直接跑在浏览器里的开源平台

PyScript 是一个”在浏览器里运行 Python”的开源平台,由 Anaconda 公司于 2022 年发起,官方自述为”open source platform for Python in the browser”。它的出发点很性感:既然 Web 是最普及的计算平台、Python 是最流行的语言之一,那为什么不能让一段 Python 代码像 HTML 一样,丢进浏览器就跑?本文基于 PyScript 官方文档与 GitHub 仓库,梳理它的运行机制、双解释器取舍,并把一个容易被首页宣传掩盖的事实——官方已宣布该项目进入维护模式——放到台面上讨论。
一、背景:Python 上 Web 的老问题
长期以来,“Python 跑在浏览器里”这件事只能靠间接手段:要么把 Python 翻译成 JavaScript(如 Brython),要么用后端服务器执行后把结果送回前端。前者要面对翻译层与原生库的鸿沟,后者则意味着任何一点交互都要一次网络往返,部署也离不开服务器。
转折点是 CPython 被成功编译成 WebAssembly。据 Koala 项目库记录,这一路线最早来自 PyCon 上关于”将 CPython 3.11 编译到 WebAssembly”的演讲,Anaconda 在此基础上封装出了 PyScript。它的卖点因此非常直接:代码运行在用户浏览器里,不需要昂贵的后端基础设施,应用分享出去”就是一个 URL”。
二、是什么:一个”平台”而非一个解释器
需要先澄清一个常见误解:PyScript 本身不是一个新的 Python 解释器。它是套在两个已有、已编译成 Wasm 的解释器之上的”平台层”。官方文档把栈分得很清楚:

- 最底层是编译成 WebAssembly 的 Python 解释器(Pyodide 或 MicroPython),由它们真正执行你的代码;
- 中间是 PolyScript——一个负责引导解释器、处理脚本求值、事件与 worker 管理的小内核;PyScript 再在其上叠加插件与易用 API;
- 跨线程协调由 Coincident 库承担,封装了主线程与 Web Worker 之间的通信、SharedArrayBuffer 与内存协调;
- 最顶层才是用户代码与选用的框架。
官方特别强调:一切都发生在浏览器标签页这个沙箱里——不在云端服务器执行,也不调用用户操作系统里安装的 Python。
三、技术机制:双解释器与 Emscripten 桥
PyScript 支持两个被编译成 Wasm 的解释器,二者取舍不同:
| 维度 | Pyodide | MicroPython |
|---|---|---|
| 本质 | CPython 编译到 Wasm | 面向受限环境的精简 Python |
| 兼容性 | 完整 Python,含标准库 | 标准库子集 |
| 包安装 | 可用 micropip 从 PyPI 安装 | 不支持安装第三方包 |
| 数据科学库 | numpy / scipy / pandas 预编译可用 | 基本没有 |
| 体积 / 启动 | 较大、首次加载较慢 | 压缩后约 170KB,启动快 |
| 适用 | 全功能、重型计算 | UI 脚本、移动端、弱网 |
两个解释器都通过 Emscripten(基于 LLVM 的编译工具链)把 C 编译成 Wasm,并由 Emscripten 在浏览器里模拟出沙箱文件系统、标准输入输出与网络能力——这就是为什么你能在 PyScript 里照常 open() 读文件、print() 输出、import 模块。Python 与 JavaScript 之间则通过统一的 pyscript.ffi 命名空间互操作,官方称两个解释器实现了几乎一致的 FFI,因此在它们之间迁移相对平滑。
实际使用只需在 HTML 里引入两行(见首图),再用 <script type="py">(Pyodide)或 <script type="mpy">(MicroPython)写 Python 即可。生命周期上,页面加载后 PyScript 作为 ES module 异步加载、下载解释器、装载包与文件,就绪后派发 py:ready(或 mpy:ready),全部脚本执行完再派发 py:done 事件。
四、关键口径:那个 170KB 与”全功能”分别指什么
官方在文档里给了一组需要精确理解的数字与说法:
- MicroPython 解释器”压缩后约 170KB”,这是与”网页上的许多图片比大小”的口径,用来凸显它适合弱网移动场景;它只在 MicroPython 这一解释器下成立,不能套用到 Pyodide。
- Pyodide 侧官方承诺”完整 Python 兼容 + 从 PyPI 装包”,但同一处用 Warning 标注了边界:带 C 扩展的包只有在被编译成 WebAssembly 后才能在 Pyodide 里工作;未为 Wasm 编译的包会报”pure Python wheel”错误。换句话说,“能装 PyPI 包”不等于”能装所有 PyPI 包”。
五、评测方法批判:官方没有给性能数字
值得注意的是,PyScript 官方文档几乎不提供吞吐、时延类 benchmark,这与它”教学/分享/原型”的定位一致——它不宣称比 Node 快。因此网上任何”PyScript 跑得多快”的说法都要额外小心:Wasm 启动时需要下载并编译解释器,首次加载体积可观,运行期又跑在浏览器单线程/Worker 沙箱里,其性能画像与原生 Python 服务端完全是两回事。官方没有掩盖这一点,而是把”大体积、慢启动”明列为选 Pyodide 的代价。
六、适用 / 不适用场景
适合:
- 教学与课堂:学生打开一个链接就能跑 Python,免去装环境;
- 数据/科研的轻量交互演示:numpy、pandas 已预编译,适合在静态页里嵌一个可交互图表;
- 不需要后端的小工具、demo、可分享原型。
不适合:
- 高并发、重计算的生产后端——它本就跑在访客浏览器里;
- 重度依赖未编译成 Wasm 的 C 扩展包的项目;
- 对首屏加载体积敏感的移动页面——此时应选 MicroPython 而非 Pyodide。
七、客观分析:优势与局限
优势:
- 零安装、即分享:应用就是一个 URL,这是传统 Python 分发很难做到的;
- 安全模型天然成立:跑在浏览器沙箱里,不碰用户真实文件系统;
- 双解释器可按需切换:要全功能用 Pyodide,要轻量快启用 MicroPython;
- 生态背靠 Pyodide:numpy/pandas/scipy 等科学计算库预编译可用。
局限(含官方口径):
- 跨解释器不兼容:官方明确警告,依赖 PyPI 包的代码只在 Pyodide 下工作;依赖完整标准库的代码在 MicroPython 下”行为可能不同或失败”,切换解释器必须充分测试;
- C 扩展受限:未编译到 Wasm 的包无法安装,这是硬约束而非配置问题;
- 首次加载成本:Pyodide 体积大、启动慢,官方自己把它列为 trade-off;
- 最重要的一条——项目状态:GitHub 仓库 README 顶部已挂出公告 “PyScript is entering maintenance mode”(进入维护模式)。这意味着它仍可用、仍有 Anaconda 核心贡献者投入,但作为技术选型,你应当把它当作一个”成熟但不再高速演进”的项目来评估,而不是一个正在快速加特性的新框架。
八、它意味着什么 / 谁该关注
PyScript 的价值不在于”用它替代后端”,而在于它验证了一件事:把 CPython 整条编译进 Wasm 后,Python 第一次真正获得了”像网页一样随处分发”的能力。对教师、数据博主、需要做可交互演示的人,它至今仍是门槛最低的方案。但如果你在为一个长期产品选技术栈,请把”维护模式”这一官方公告读进去——它更适合做一次性、分享型、教学型的轻应用,而不是作为未来数年重度依赖的核心前端运行时。