一、PyScript 简介与发展历程
PyScript 是一个开源框架,让开发者可以在 HTML 页面中直接使用 Python 编写前端逻辑。底层依赖于 Pyodide(CPython 编译为 WebAssembly),从而在浏览器中运行 Python 脚本,无需服务器环境。
发展时间线:
- 2022.4:发布首个演示版本
- 2023.x:引入
<py-script>
标签,支持 display、micropip - 2024.x:模块化构建核心
- 2025.7.1:移除
<py-script>
,采用<script type="py">
,全面支持模块化 + fetch
PyScript 的目标是让 Python 开发者无需切换语言即可创建前端页面,尤其适用于教学、数据展示、交互式应用等。
二、Hello PyScript —— 快速上手
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="https://pyscript.net/releases/2025.7.1/core.css" />
<script type="module" src="https://pyscript.net/releases/2025.7.1/core.js"></script>
</head>
<body>
<h1>Hello PyScript</h1>
<script type="py">
from pyscript import display
import sys
display(f"当前 Python 版本: {sys.version}")
</script>
</body>
</html>
三、核心语法与常用 API
输出到页面
from pyscript import display
display("Hello, PyScript!")
操作 DOM
from js import document
document.getElementById("output").innerText = "我来自 Python"
异步 Fetch 请求
from pyscript import fetch
import asyncio
async def get_data():
res = await fetch("https://api.github.com")
data = await res.json()
display(data)
asyncio.ensure_future(get_data())
事件绑定与回调函数
<input id="name" /> <button id="greet">打招呼</button>
<div id="result"></div>
from js import document
def greet(event):
name = document.getElementById("name").value
document.getElementById("result").innerText = f"你好,{name}!"
document.getElementById("greet").addEventListener("click", greet)
访问浏览器对象
from js import window, navigator
display(f"用户代理: {navigator.userAgent}")
display(f"浏览器宽度: {window.innerWidth}px")
调用 JavaScript 函数
<script>
function js_add(a, b) {
return a + b;
}
</script>
from js import js_add
result = js_add(3, 5)
display(f"3 + 5 = {result}")
使用 setTimeout / setInterval
from js import setTimeout, setInterval
counter = 0
def tick():
global counter
counter += 1
display(f"已过去 {counter} 秒")
setInterval(tick, 1000)
错误处理与调试
try:
1 / 0
except ZeroDivisionError as e:
display(f"捕获错误:{e}")
finally:
display("执行完成")
动态加载 Python 代码
from pyodide import run_python_async
await run_python_async("display('动态执行代码')")
四、标准库与第三方库支持
PyScript 使用 Pyodide,支持以下:
内置标准库
- math, random, datetime, json
- asyncio, os(部分)
可安装的第三方库(via micropip)
- numpy
- pandas
- matplotlib
- scikit-learn
配置方法
<script type="py-config">
{
"packages": ["pandas", "matplotlib"]
}
</script>
五、文件交互
文件上传
<input type="file" id="file" />
<pre id="output"></pre>
async def read_file(event):
file = event.target.files[0]
text = await file.text()
document.getElementById("output").innerText = text
document.getElementById("file").addEventListener("change", read_file)
文件下载
from js import Blob, URL, document
def download(content, filename="output.txt"):
blob = Blob.new([content], { "type": "text/plain" })
url = URL.createObjectURL(blob)
link = document.createElement("a")
link.href = url
link.download = filename
link.click()
download("Hello from PyScript!")
六、实战项目 1 - Todo 应用
<input id="task-input" placeholder="添加任务" />
<button id="add-btn">添加</button>
<ul id="task-list"></ul>
<style>
.done { text-decoration: line-through; color: gray; }
</style>
from js import document
task_input = document.getElementById("task-input")
task_list = document.getElementById("task-list")
def add_task(event):
text = task_input.value.strip()
if text:
li = document.createElement("li")
li.innerText = text
li.onclick = lambda e: li.classList.toggle("done")
task_list.appendChild(li)
task_input.value = ""
document.getElementById("add-btn").addEventListener("click", add_task)
七、实战项目 2 - 数据可视化
import pandas as pd
import matplotlib.pyplot as plt
s = pd.Series([30, 50, 20], index=["A", "B", "C"])
s.plot(kind='bar')
plt.savefig("/mnt/data/chart.png")
from js import document
img = document.createElement("img")
img.src = "/mnt/data/chart.png"
document.body.appendChild(img)
八、实战项目 3 - ChatGPT 小助手
Flask 后端
from flask import Flask, request, jsonify
import openai
app = Flask(__name__)
openai.api_key = "your_api_key"
@app.route("/chat", methods=["POST"])
def chat():
prompt = request.json.get("prompt", "")
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
)
return jsonify({"answer": response.choices[0].message.content})
前端页面 + 脚本
<textarea id="input"></textarea>
<button id="ask">发送</button>
<div id="reply"></div>
from js import document
from pyscript import fetch
import asyncio
async def send():
question = document.getElementById("input").value
res = await fetch("/chat", method="POST",
headers={"Content-Type": "application/json"},
body=f'{{"prompt": "{question}"}}')
data = await res.json()
document.getElementById("reply").innerText = data.get("answer", "失败")
document.getElementById("ask").addEventListener("click", lambda e: asyncio.ensure_future(send()))
项目结构建议
pyscript-chatgpt/
├── index.html
├── main.py
├── style.css
├── /assets
└── README.md
- 使用
<script type="py" src="main.py">
可引入外部脚本 - 推荐部署至 GitHub Pages、Netlify 等静态服务平台
九、结语
PyScript 为 Python 带来了真正的“前端权力”,无需 JS,就能开发交互应用。
它适合教学、科学计算可视化、数据工具原型、甚至 AI 助手等现代场景。愿你用 PyScript 开启下一段创作之旅。
十、参考
官方网站: https://docs.pyscript.net
《Python 前端框架/工具合集》