Pyodide

Pyodide 是一个在浏览器环境中运行的 Python 解释器,利用了 CPython 技术和 WebAssembly 技术,从而可以在浏览器中运行 Python 软件包;并且 Pyodide 保证了 Python 与 JavaScript 的兼容,允许 Python 使用浏览器的 API

基本使用

使用 CDN 形式向项目中引入 Pyodide 软件包

1
<script defer src="https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"></script>

然后调用已注入到全局的 loadPyodide() 方法获取到 Pyodide 实例

1
const pyodide = await loadPyodide()

调用 Pyodide 实例的 runPython() 方法以执行 Python 代码

该方法传入的字符串,代表需要执行的 Python 代码

该方法的返回值,执行 Python 代码的输出

1
pyodide.runPython(`print('Hello world!')`)

调用 print() 方法的效果相当于调用 console.log() 方法

1
2
3
4
5
6
pyodide.runPython('1 + 2')
pyodide.runPython('2 ** 10')
pyodide.runPython(`
import sys
sys.version
`)

同样可以在 Pyodide 中使用内置软件包,也可以导入外部软件包

Pyodide 实例的 runPythonAsync() 方法用于异步执行 Python 代码

1
await pyodide.runPythonAsync('1 * 1')

JS 获取 Python 作用域

Python 全局作用域通过 pyodide.globals 对象暴露

调用其 get() 方法以获取 Python 全局作用域的变量

1
2
3
4
5
6
7
pyodide.runPython('x = 1')
pyodide.runPython(`y = 'xes'`)
pyodide.runPython('z = [2, 4]')

pyodide.globals.get('x')
pyodide.globals.get('y')
pyodide.globals.get('z').toJs()

Python 中复杂类型变量,如列表等,可以通过调用 toJs() 来转换为一个 JS 对象

调用其 set() 方法以设置 Python 全局作用域的变量

1
2
3
4
5
6
7
pyodide.globals.set('xx', 'xxxxx')
pyodide.globals.set('alert', alert)
pyodide.globals.set('square', x => x ** 2)

pyodide.runPython('print(xx)')
pyodide.runPython(`alert('xxxx')`)
pyodide.runPython('print(square(20))')

可以设置普通变量、对象、函数,以及 JS 或 DOM 内置函数等等

Python 获取 JS 作用域

在 Python 中导入 JS 包以使用 JS 的全局变量

1
2
3
import js

js.confirm('message')

使用类似与调用 window 变量

Worker 环境使用

使用 importScripts() 方法导入 CDN 脚本,随后通过暴露在全局的 loadPyodide() 方法使用

1
self.importScripts("https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js")

特别的,若在 ServiceWorker 中使用,需要导入 XMLHttpRequest 的 shim 包,因为该类在 ServiceWorker 中无法使用但 Pyodide 依赖于该包,如

1
2
importScripts("./node_modules/xhr-shim/src/index.js")
self.XMLHttpRequest = self.XMLHttpRequestShim

模块 Worker 环境下需要改变导入方式为 ESM

1
2
3
4
import "./node_modules/xhr-shim/src/index.js"
self.XMLHttpRequest = self.XMLHttpRequestShim
import "./pyodide.asm.js"
import { loadPyodide } from "./pyodide.mjs"

文件系统

Pyodide 基于 Emscripten File System API 实现了自定义的文件系统

在 Python 环境中直接调用相关文件操作方法;通过 pyodide.FS 对象向浏览器环境暴露对文件系统的操作

1
2
3
4
5
6
7
with open("/hello.txt", "r") as fh:
data = fh.read()
print(data)

with open("/hello.txt", "r") as fh:
data = fh.read()
print(data)
1
2
3
const file = pyodide.FS.readFile("/hello.txt", { encoding: "utf8" })

pyodide.FS.writeFile("/hello.txt", data, { encoding: "utf8" })

需要注意的是,Pyodide 默认使用的是 MEMFS,可以通过调用其 mount 方法绑定至其他的文件系统

1
pyodide.FS.mount(pyodide.FS.filesystems.NODEFS, { root: "." }, "/mnt")

或者可以使用原生 File System API 绑定至 Origin Private File System 或 Native File System

1
2
3
4
5
const root = await navigator.storage.getDirectory()

const nativefs = await pyodide.mountNativeFS("/mnt", root)

await nativefs.syncfs()
发布于

2023-11-01

更新于

2023-11-10

许可协议

评论

:D 一言句子获取中...

加载中,最新评论有1分钟缓存...