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 | pyodide.runPython('1 + 2') |
同样可以在
Pyodide
中使用内置软件包,也可以导入外部软件包
Pyodide
实例的 runPythonAsync()
方法用于异步执行 Python 代码
1 | await pyodide.runPythonAsync('1 * 1') |
JS 获取 Python 作用域
Python 全局作用域通过 pyodide.globals
对象暴露
调用其 get()
方法以获取 Python 全局作用域的变量
1 | pyodide.runPython('x = 1') |
Python 中复杂类型变量,如列表等,可以通过调用
toJs()
来转换为一个 JS 对象
调用其 set()
方法以设置 Python 全局作用域的变量
1 | pyodide.globals.set('xx', 'xxxxx') |
可以设置普通变量、对象、函数,以及 JS 或 DOM 内置函数等等
Python 获取 JS 作用域
在 Python 中导入 JS 包以使用 JS 的全局变量
1 | import js |
使用类似与调用 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 | importScripts("./node_modules/xhr-shim/src/index.js") |
模块 Worker 环境下需要改变导入方式为 ESM
1 | import "./node_modules/xhr-shim/src/index.js" |
文件系统
Pyodide 基于 Emscripten File System API 实现了自定义的文件系统
在 Python 环境中直接调用相关文件操作方法;通过 pyodide.FS
对象向浏览器环境暴露对文件系统的操作
1 | with open("/hello.txt", "r") as fh: |
1 | const file = pyodide.FS.readFile("/hello.txt", { 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 | const root = await navigator.storage.getDirectory() |