当前位置:首页>python>浏览器里的 Python,为什么可以运行?

浏览器里的 Python,为什么可以运行?

  • 2026-10-22 17:29:21
浏览器里的 Python,为什么可以运行?

在菜鸟教程里,点一下“运行”,Python 立刻有了输出。

可浏览器本身并不认识 Python:这段代码究竟被谁接住,又是怎样回到页面上的?

菜鸟教程代码运行示例

代码走过四站

流程图负责说明先后顺序;每一站的插画,负责说明这一站到底在做什么。

浏览器代码运行的四个阶段

01 代码块交出输入

代码围栏不负责运行,只交出语言和源码。dataset 读取语言,textContent 读取代码,合成输入对象。

阶段一:读取代码和语言
type CodeInput = { language: string; code: string };const card = document.querySelector<HTMLElement>("[data-example]")!;const input: CodeInput = {  language: card.dataset.language ?? "",  code: card.querySelector("[data-code]")?.textContent ?? "",};

得到:{ language, code }。

02 适配器组装 Runner

页面只调用统一的 run。createRunner 根据语言选适配器,适配器再连接运行时。

阶段二:适配器选择 Runner
type CodeRunner = {  run(code: string): Promise<RunResult>;  dispose(): void;};function createRunner(language: string): CodeRunner {  if (language === "python") {    return createWorkerRunner("./workers/python.worker.js");  }  throw new Error("暂未注册 Runner");}

Python 是当前注册的第一种语言。

03 Worker 里真正执行

Runner 创建 Worker,把代码发过去。Worker 加载 Pyodide,用 setStdout 接住输出,再用 runPythonAsync 执行。

阶段三:Worker 使用 Pyodide 执行
// 主线程const worker = new Worker(workerUrl);worker.postMessage({ type: "run", code });// workers/python.worker.jsself.onmessage = async ({ data }) => {  const pyodide = await loadPyodide({ indexURL: PYODIDE_INDEX_URL });  let stdout = "";  pyodide.setStdout({ batched:text => (stdout += text) });  await pyodide.runPythonAsync(data.code);  self.postMessage({ type: "result", ok: true, stdout });};

workers/python.worker.js 是项目自己写的承载文件。

04 消息带着结果回来

Worker 完成后用 postMessage 回传结果,主线程在 onmessage 中把 stdout 或 stderr 写进输出面板。

阶段四:消息带回执行结果
worker.onmessage = ({ data }) => {  if (data.type !== "result") return;  output.textContent = data.ok ? data.stdout : data.stderr;};

页面看到的是统一结果,不需要知道 Python 内部怎么跑。

回头看刚才的点击:代码块交出字符串,Runner 找到运行时,Worker 完成计算,消息把结果带回页面。

换成其它语言呢?

只替换语言适配器:JavaScript 可以用原生 Worker,SQL 可以接 SQLite-Wasm 或 DuckDB-Wasm。代码块、消息格式和输出面板都能继续复用。

它还能做什么?

教程里的可运行示例、浏览器内的数据处理和 SQL 小工具、无需上传代码的交互式练习,都可以沿用这条“输入 → 执行 → 输出”的路径。

最新文章

随机文章