PyScript Python in Browser

FreeGuideOnline 最新 2026-07-15

PyScript:在浏览器中运行 Python 的完全指南

欢迎来到 PyScript 的世界!本教程将带你从零开始,了解如何使用 PyScript 在网页中直接编写和运行 Python 代码。无需复杂的后端配置,只需浏览器,即可创建交互式的 Python 应用。

无论你是 Web 开发者还是 Python 爱好者,读完这篇教程,你都将能够:

  • 在 HTML 文件中嵌入 Python 代码
  • 操作 DOM,实现前端交互
  • 利用 Python 生态中的常用库(如 NumPy、Matplotlib)
  • 打包你的应用并分享给他人

1. 什么是 PyScript?

PyScript 是一个开源框架,它基于 Pyodide(一个将 CPython 编译到 WebAssembly 的项目),让你能在浏览器中直接运行 Python 代码。
它由 Anaconda 团队主导开发,旨在将 Python 的强大生态引入前端世界。

简单来说,过去你只能在服务器端使用 Python,然后通过 API 把结果传给浏览器;而现在,你可以把 Python 当成前端语言 来使用,直接在 <script> 标签中编写脚本,操作网页元素。

核心优势:

  • 零安装:用户无需安装 Python 解释器,一切都运行在浏览器沙箱中。
  • 与 HTML/CSS 无缝集成:Python 可以实时读写 DOM。
  • 丰富的库支持:预置了大量科学计算和可视化库(Pyodide 项目维护了可运行在 WASM 上的包列表)。
  • 简单部署:最终产物就是普通的 HTML 文件,上传到任何静态服务器即可。

2. 环境准备与第一个 PyScript 页面

你不需要安装任何软件,只需要一个现代浏览器(推荐 Chrome、Firefox 或 Edge)和一个代码编辑器(如 VS Code)。

2.1 一个最简单的例子

创建一个文件 hello.html,内容如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>我的第一个 PyScript 页面</title>
    <link rel="stylesheet" href="https://pyscript.net/releases/2024.08.1/core.css">
    <script type="module" src="https://pyscript.net/releases/2024.08.1/core.js"></script>
</head>
<body>
    <h1>PyScript 演示</h1>
    <py-script>
        print("Hello, 浏览器中的 Python!")
    </py-script>
</body>
</html>

用浏览器打开这个文件,你会看到:

  • 页面上显示 “PyScript 演示”
  • 同时在输出区域(默认是一个黑色终端风格的面板)中打印了 Hello, 浏览器中的 Python!

版本说明:本教程使用 PyScript 2024.08.1。如果日后有更新,请参考 官方文档 调整资源链接。

2.2 <py-script> 标签

<py-script> 是 PyScript 提供的最核心的自定义元素,所有放在这个标签内的代码都会被作为 Python 执行。
你可以在一页中放置多个 <py-script>,它们共享同一个全局命名空间。


3. 与网页元素交互

PyScript 可以像 JavaScript 一样操作 DOM,而且语法更加 Pythonic。

3.1 使用 Element 读写 HTML 元素

首先,你需要给目标元素一个 id 属性,然后在 Python 中通过 Element 类来获取它。

示例:制作一个点击计数器

<button id="my-btn" py-click="counter()">点击我!</button>
<p>点击次数:<span id="count-display">0</span></p>

<py-script>
    count = 0

    def counter():
        global count
        count += 1
        Element("count-display").write(count)
</py-script>

代码解释:

  • py-click="counter()" 是 PyScript 的事件绑定属性,当按钮被点击时执行 Python 函数。
  • Element("count-display") 获取 id 为 count-display 的元素。
  • .write() 方法设置该元素的文本内容。

3.2 获取用户输入

你也可以轻松读取输入框的值:

<input type="text" id="name-input" placeholder="输入你的名字">
<button id="greet-btn" py-click="greet()">打招呼</button>
<div id="greeting"></div>

<py-script>
    def greet():
        name = Element("name-input").value
        greeting_text = f"你好,{name or '陌生人'}!"
        Element("greeting").write(greeting_text)
</py-script>

3.3 常见事件属性

PyScript 支持一系列以 py- 开头的事件属性,可以直接内联在 HTML 元素上:

属性 触发时机 示例
py-click 元素被点击时 py-click="my_func()"
py-change 内容变化时(如输入框) py-change="on_change()"
py-keydown 按键按下时 py-keydown="on_key()"
py-mouseover 鼠标悬浮时 py-mouseover="hover()"

你还可以使用 when 装饰器实现更灵活的事件监听(后面会介绍)。


4. 使用 Python 库

PyScript 底层依赖 Pyodide,因此你可以直接使用 Pyodide 支持的第三方库。部分常用库(如 numpy, pandas, matplotlib)已经预加载,你可以在 <py-script> 中直接 import

4.1 使用 NumPy 进行数学计算

<py-script>
    import numpy as np
    arr = np.array([1, 2, 3, 4, 5])
    result = np.mean(arr)
    Element("numpy-result").write(f"平均值是: {result}")
</py-script>

<div id="numpy-result"></div>

4.2 绘制图表(Matplotlib)

使用 Matplotlib 时,需要稍微调整一下输出方式,让图像显示在网页上。

<div id="chart"></div>
<py-script>
    import matplotlib.pyplot as plt
    import numpy as np

    x = np.linspace(0, 2 * np.pi, 100)
    y = np.sin(x)

    fig, ax = plt.subplots()
    ax.plot(x, y)
    ax.set_title("正弦波")

    # 将图表渲染到 id 为 chart 的元素中
    display(fig, target="chart", append=False)
</py-script>

display() 函数是 PyScript 提供的,可以从 Python 向 HTML 输出多种对象,包括 Matplotlib 图像。

提示:如果你想使用未被预装的库(如 requests),可以使用 <py-config> 标签手动加载,或者通过 micropip 在运行时安装。


5. 使用 <py-config> 配置环境

<py-config> 标签用于声明 Python 环境配置,比如要额外安装的包、本地文件路径等。将它放在 <head><body> 的最前面。

5.1 安装第三方包

例如,你需要使用 requests 库:

<py-config>
    packages = ["requests"]
</py-config>

<py-script>
    import requests
    response = requests.get("https://api.github.com")
    print("GitHub API 状态码:", response.status_code)
</py-script>

<py-config> 内采用 TOML 格式。更复杂的配置可以这样写:

<py-config>
    [splashscreen]
    enabled = false

    [[fetch]]
    files = ["./data.csv"]
</py-config>

5.2 加载本地文件

如果你的应用需要读取用户上传的文件或本地数据,可以使用 [[fetch]] 声明文件列表,PyScript 会在运行时将其加载到虚拟文件系统中,供 Python 代码访问。


6. 深入事件处理:when 装饰器

除了内联的 py-* 属性,PyScript 还提供了更现代的 when 装饰器,可以在纯 Python 代码中绑定事件。

示例:通过 when 实现按钮点击

<button id="decorated-btn">点击我(装饰器版)</button>
<div id="decorated-output"></div>

<py-script>
    from pyscript import when

    @when("click", "#decorated-btn")
    def on_click(event):
        Element("decorated-output").write("你点击了按钮!")
</py-script>

@when 接收两个参数:事件类型和选择器(CSS 选择器,如 #id, .class)。
这种方式使逻辑与 HTML 标记更解耦,尤其适合复杂的 Web 应用。


7. 创建实时交互应用:一个完整示例

让我们结合上述知识点,构建一个简单的 待办事项(Todo)列表 应用。

完整代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>PyScript 待办事项</title>
    <link rel="stylesheet" href="https://pyscript.net/releases/2024.08.1/core.css">
    <script type="module" src="https://pyscript.net/releases/2024.08.1/core.js"></script>
</head>
<body>
    <h2>📝 我的待办事项</h2>
    <input type="text" id="task-input" placeholder="输入任务...">
    <button id="add-btn">添加</button>
    <ul id="task-list"></ul>

    <py-script>
        from pyscript import when, Element

        tasks = []

        def render_tasks():
            task_list_element = Element("task-list")
            # 清空当前列表
            task_list_element.clear()
            for idx, task in enumerate(tasks):
                li = document.createElement("li")   # 可以直接使用 document 对象
                li.innerHTML = f"{task} <button class='delete-btn' data-index='{idx}'>删除</button>"
                task_list_element.element.appendChild(li)

        @when("click", "#add-btn")
        def add_task(evt):
            input_element = Element("task-input")
            task_text = input_element.value.strip()
            if task_text:
                tasks.append(task_text)
                input_element.clear()
                render_tasks()

        @when("click", ".delete-btn")   # 动态创建的元素也能绑定(事件委托有效)
        def delete_task(evt):
            # 从按钮的 data-index 属性获取删除的任务索引
            index = int(evt.target.getAttribute("data-index"))
            tasks.pop(index)
            render_tasks()
    </py-script>
</body>
</html>

操作说明

  • 在输入框中输入任务名称,点击“添加”,任务会出现在下方列表。
  • 每个任务右侧有一个“删除”按钮,点击即可移除对应任务。
  • 任务列表由 Python 列表 tasks 驱动,每次操作后重新渲染。

注意:这里我们使用了 document 对象,它是 PyScript 全局可用的浏览器 Document 对象,允许你使用熟悉的 DOM API。


8. 调试与常见问题

8.1 查看输出与错误

默认情况下,print() 的输出和 Python 异常会显示在页面下方的终端面板中。
如果面板被隐藏,可以按 Ctrl+Shift+O (Windows/Linux) 或 Cmd+Shift+O (Mac) 打开开发者控制台查看错误。

8.2 加载速度慢怎么办?

初次加载 PyScript 页面时,浏览器需要下载 Pyodide 运行时(约 8-12 MB),可能会有几秒延迟。
优化建议:

  • 使用 CDN 加速(本教程使用的已经是)。
  • <py-config> 中设置 preload 列表,仅加载真正用到的包。
  • 提供友好的加载提示(可以通过 <py-splashscreen> 自定义启动画面)。

8.3 想使用 input() 函数?

PyScript 默认的 input() 是阻塞式的,并不适合浏览器环境。你应该使用 HTML 输入框并通过事件读取值,就像前面示例那样。


9. 部署与分享

你完成的 PyScript 应用就是一个静态网站,只需要把它托管到任意 HTTP 服务器即可。

几种简单的方式:

  • 本地测试:直接用浏览器打开 HTML 文件(某些功能可能需要通过 HTTP 服务才能正常工作,推荐使用 VS Code 的 Live Server 插件)。
  • 在线发布:上传到 GitHub Pages、Netlify、Vercel 等静态托管平台。

无需后端代码,无需配置 Python 环境,用户只要能访问网页就能使用你的应用。


10. 局限性与未来

虽然 PyScript 打开了新的大门,但目前仍有以下限制:

  • 执行效率不如原生编译,大量计算任务可能较慢(但 WebAssembly 在持续优化)。
  • 库支持依賴 Pyodide 包的移植,不是所有 Python 包都能用。
  • 包体积较大,初次访问等待时间较长。
  • 无法调用客户端系统 API,受浏览器安全策略限制。

尽管如此,PyScript 正在快速发展,社区生态也在不断完善。对于教育、数据演示、轻量级工具等场景,它已经足够强大。


结语

恭喜你完成了 PyScript 的基础入门!你现在已经能够:

  • 在网页中运行 Python 并操作 DOM
  • 使用 numpy、matplotlib 等常用库
  • 构建交互式的 Todo 应用
  • 了解配置、事件处理和部署方法

下一步,你可以尝试:

用 Python 重塑网页体验,现在就开始吧!