Pyodide环境可通过检测window.pyodide存在且为对象,或sys.platform=="emscripten"来可靠识别;需同时排除Electron、Node.js等干扰环境,避免仅依赖window或sys.implementation.name。

检查 window 和 pyodide 全局对象是否存在
Pyodide 运行在浏览器 Web Worker 或主线程中,会向全局作用域注入 window(或 self)和 pyodide 对象。最直接的判断方式是检测这两个标识符是否可访问且类型正确:
-
window存在且为object(排除 Node.js 或纯 CLI 环境) -
window.pyodide存在且为对象(不是undefined或null) - 避免仅检查
window—— 比如 Electron、NW.js 也有window,但不是 Pyodide
实操建议:
def is_pyodide():
try:
import sys
if "pyodide" in sys.modules:
return True
# fallback: check global JS scope
from js import window
return hasattr(window, "pyodide") and window.pyodide is not None
except (ImportError, AttributeError):
return False
利用 sys.platform 和 sys.implementation.name 辅助识别
Pyodide 的 sys.platform 固定为 "emscripten",sys.implementation.name 是 "cpython"(注意:不是 "pyodide"),这点和 CPython 本体不同但和 Emscripten 编译目标一致。
-
sys.platform == "emscripten"是强信号,几乎只出现在 Pyodide / Emscripten 环境 - 单独依赖
sys.implementation.name == "cpython"不可靠 —— 标准 CPython 也返回这个值 - 组合使用更稳妥:
sys.platform == "emscripten"+"pyodide" in sys.modules
避免误判:Node.js、Jest、Electron 的干扰项
有些环境也会暴露 window 或模拟浏览器 API,导致简单判断出错:
立即学习“Python免费学习笔记(深入)”;
- Jest 测试环境可能有
window,但没有pyodide对象 - Electron 主进程无
window,渲染进程有window但无pyodide - Node.js 里
globalThis.window是undefined,但某些 polyfill 库可能挂载空对象
因此必须把 pyodide 对象存在性作为必要条件,而不是仅靠运行时平台字符串或全局变量名。
生产代码中推荐的健壮检测函数
综合上述,一个低侵入、不抛异常、兼容导入时机的检测方式:
def is_pyodide():
try:
from js import window
if hasattr(window, "pyodide") and window.pyodide:
return True
except ImportError:
pass
try:
import sys
if sys.platform == "emscripten":
return True
except AttributeError:
pass
return False
注意:该函数在非浏览器环境(如本地 Python)中不会触发 js 模块导入失败以外的副作用;is_pyodide() 返回 True 时,基本可以安全调用 pyodide.loadPackage 或读取 js.document —— 但别忘了,js 模块本身只在 Pyodide 初始化完成后才可用,所以首次检测最好放在 main() 或事件回调中,而非模块顶层。










