如何在网页中直接运行 Python 代码(无需服务器)

来源:AI社区作者:马来西亚程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《如何在网页中直接运行 Python 代码(无需服务器)》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在网页中直接运行 Python 代码(无需服务器)》有用,将其分享出去将是对创作者最好的鼓励。

在网页中直接运行Python代码且不需要服务器支持,核心思路是利用WebAssembly技术将Python解释器移植到浏览器环境中,目前最成熟的方案是借助Pyodide实现。Pyodide是Mozilla开发的项目,它把Python解释器和常用的科学计算库都编译成了WebAssembly格式,能在浏览器里完整运行Python代码,不需要和后端服务器做任何交互。

如何在网页中直接运行 Python 代码(无需服务器)

核心实现原理

Pyodide的工作流程主要分为几个步骤,首先浏览器加载Pyodide的运行时文件,这部分文件包含了编译后的Python解释器核心。接着运行时会在浏览器的内存中初始化一个独立的Python执行环境,这个环境和浏览器的JavaScript环境是相互隔离的,但是可以通过特定的API进行数据交互。当用户输入Python代码后,Pyodide会把代码交给内存中的Python解释器执行,执行结果再返回给前端页面展示。

基础环境引入

要在网页中使用Pyodide,首先需要在HTML页面中引入Pyodide的CDN资源,不需要做任何服务器端的配置,直接通过公共CDN加载即可。引入完成后需要等待Pyodide初始化完成,才能调用相关的API执行Python代码。

下面是引入Pyodide的基础HTML代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>网页运行Python代码</title>
</head>
<body>
    <!-- 引入Pyodide CDN -->
    <script src="https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"></script>
    <script>
        // 后续逻辑写在这里
    </script>
</body>
</html>

执行简单Python代码

Pyodide初始化完成后,会提供一个pyodide全局对象,通过这个对象的runPython方法就可以执行Python代码字符串,方法会返回Python代码的执行结果。需要注意的是初始化是异步过程,所以需要用async/await语法处理。

下面的示例实现了一个简单的功能,在网页中执行Python的加法计算,并把结果展示在页面上:

async function runPythonCode() {
    // 等待Pyodide初始化完成
    let pyodide = await loadPyodide();
    // 要执行的Python代码
    let pythonCode = `
a = 10
b = 20
result = a + b
result
`;
    // 执行Python代码并获取结果
    let output = pyodide.runPython(pythonCode);
    // 把结果展示到页面
    document.getElementById("output").innerText = "计算结果:" + output;
}
// 页面加载完成后初始化
window.onload = function() {
    runPythonCode();
};

对应的HTML展示部分代码:

<div>
    <p>Python执行结果区域:</p>
    <p id="output"></p>
</div>

处理Python的输入输出

如果Python代码中包含print输出或者需要获取用户输入,需要做额外的处理。Pyodide默认不会把print的内容直接返回,我们可以通过重定向标准输出来捕获这些内容。而对于输入,我们可以给Python环境注入自定义的函数来处理。

捕获print输出

下面的示例演示如何捕获Python代码中print的内容:

async function runPythonWithPrint() {
    let pyodide = await loadPyodide();
    // 存储print输出的数组
    let outputList = [];
    // 重定向标准输出,把print的内容存入数组
    pyodide.setStdout({
        write: (text) => {
            outputList.push(text);
        }
    });
    let pythonCode = `
print("Hello from Python")
print("当前Python版本:", "3.11")
x = 5 * 6
print("5乘以6的结果是:", x)
`;
    pyodide.runPython(pythonCode);
    // 拼接所有输出内容
    document.getElementById("printOutput").innerText = outputList.join("");
}

模拟input输入

如果Python代码中用到了input函数,我们可以通过给Pyodide注入input函数的方式来模拟用户输入,下面的示例展示了如何实现:

async function runPythonWithInput() {
    let pyodide = await loadPyodide();
    // 模拟input函数,返回预设的输入值
    pyodide.globals.set("input", () => {
        return "测试输入内容";
    });
    let pythonCode = `
user_input = input("请输入内容:")
print("你输入的内容是:", user_input)
`;
    let outputList = [];
    pyodide.setStdout({
        write: (text) => {
            outputList.push(text);
        }
    });
    pyodide.runPython(pythonCode);
    document.getElementById("inputOutput").innerText = outputList.join("");
}

安装Python第三方库

Pyodide默认已经包含了很多常用的Python库,比如numpypandasmatplotlib等,如果需要使用额外的库,可以通过pyodide.loadPackage方法加载,加载完成后就可以在Python代码中正常导入使用。

下面的示例演示如何加载numpy库并使用:

async function runPythonWithLib() {
    let pyodide = await loadPyodide();
    // 加载numpy库,加载是异步过程
    await pyodide.loadPackage("numpy");
    let pythonCode = `
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
mean_value = np.mean(arr)
mean_value
`;
    let result = pyodide.runPython(pythonCode);
    document.getElementById("libOutput").innerText = "数组平均值:" + result;
}

注意事项

  • Pyodide的初始化文件体积比较大,首次加载可能需要几秒钟时间,建议添加加载状态提示,提升用户体验。
  • 浏览器环境的内存有限,不适合运行非常消耗资源的Python代码,比如处理超大文件或者复杂的机器学习训练任务。
  • 不同的Pyodide版本支持的Python库可能有差异,使用前可以查看对应版本的官方文档确认支持的库列表。
  • Pyodide运行在浏览器沙箱中,无法直接访问用户的本地文件系统,所有文件操作只能在浏览器分配的内存空间中进行。

完整示例页面

下面是一个完整的可运行页面代码,整合了上述的功能,用户可以直接把代码保存为HTML文件,用浏览器打开即可测试:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>网页直接运行Python代码</title>
    <style>
        .container { max-width: 800px; margin: 20px auto; padding: 0 20px; }
        .section { margin: 20px 0; padding: 15px; border: 1px solid #eee; }
        button { padding: 8px 16px; margin: 5px; cursor: pointer; }
        .output { min-height: 40px; padding: 10px; background: #f5f5f5; margin-top: 10px; }
    </style>
</head>
<body>
    <div class="container">
        <h1>网页无服务器运行Python代码</h1>
        <div class="section">
            <h3>基础计算</h3>
            <button onclick="runBasic()">执行基础计算</button>
            <div class="output" id="basicOutput"></div>
        </div>
        <div class="section">
            <h3>带print输出</h3>
            <button onclick="runPrint()">执行带print的代码</button>
            <div class="output" id="printOutput"></div>
        </div>
        <div class="section">
            <h3>使用numpy库</h3>
            <button onclick="runNumpy()">执行numpy计算</button>
            <div class="output" id="numpyOutput"></div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"></script>
    <script>
        let pyodideInstance = null;
        // 初始化Pyodide
        async function initPyodide() {
            if (!pyodideInstance) {
                pyodideInstance = await loadPyodide();
            }
            return pyodideInstance;
        }
        async function runBasic() {
            let pyodide = await initPyodide();
            let code = `2 ** 10`;
            let result = pyodide.runPython(code);
            document.getElementById("basicOutput").innerText = "2的10次方结果:" + result;
        }
        async function runPrint() {
            let pyodide = await initPyodide();
            let outputList = [];
            pyodide.setStdout({
                write: (text) => { outputList.push(text); }
            });
            let code = `
print("这是Python的print输出")
print("100以内偶数之和:", sum(range(0, 101, 2)))
`;
            pyodide.runPython(code);
            document.getElementById("printOutput").innerText = outputList.join("");
        }
        async function runNumpy() {
            let pyodide = await initPyodide();
            await pyodide.loadPackage("numpy");
            let code = `
import numpy as np
arr = np.arange(1, 11)
sum_val = np.sum(arr)
sum_val
`;
            let result = pyodide.runPython(code);
            document.getElementById("numpyOutput").innerText = "1到10的和:" + result;
        }
    </script>
</body>
</html>

PythonPyodideWebAssembly前端运行Python修改时间:2026-06-14 04:52:02

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。