React中使用新版Pyodide执行Python报错求助
问题:React中升级Pyodide版本后加载失败,无法使用OpenCV
我是React和Pyodide新手,希望实现可调用OpenCV功能的代码。当前使用Pyodide v0.18.1的代码可正常运行,能使用numpy等库,但该版本不支持OpenCV;而后续版本均支持OpenCV,不过将版本号改为0.18.1以上后,调用loadPyodide()时会报错。
原运行代码
import React, { useState } from 'react'; let pyodidePromise = null; let pyodideLoading = false; const loadPyodide = async () => { if (!pyodidePromise && !pyodideLoading) { pyodideLoading = true; pyodidePromise = window.loadPyodide({ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.18.1/full/" }); const pyodide = await pyodidePromise; await pyodide.loadPackage(['numpy']); //, 'opencv-python']); pyodideLoading = false; } return pyodidePromise; }; const runPythonScript = async (code) => { const pyodide = await loadPyodide(); return await pyodide.runPythonAsync(code); }; const ImageUploader = () => { ... const callPython = async () => { ... const scriptText = await (await fetch(script)).text(); const out = await runPythonScript(`${scriptText}\nmain(${JSON.stringify(args)})`); ... }; ...
报错信息(以v0.22.1为例)
load-pyodide.js:23 GET https://cdn.jsdelivr.net/pyodide/v0.21.1/full/packages.json 404 initializePackageIndex @ load-pyodide.js:23 loadPyodide @ pyodide.js:215 loadPyodide @ App.js:12 runPythonScript @ App.js:24 callPython @ App.js:59 await in callPython (async) callCallback @ react-dom.development.js:4164 invokeGuardedCallbackDev @ react-dom.development.js:4213 invokeGuardedCallback @ react-dom.development.js:4277 invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291 executeDispatch @ react-dom.development.js:9041 processDispatchQueueItemsInOrder @ react-dom.development.js:9073 processDispatchQueue @ react-dom.development.js:9086 dispatchEventsForPlugins @ react-dom.development.js:9097 (anonymous) @ react-dom.development.js:9288 batchedUpdates$1 @ react-dom.development.js:26140 batchedUpdates @ react-dom.development.js:3991 dispatchEventForPluginEventSystem @ react-dom.development.js:9287 dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465 dispatchEvent @ react-dom.development.js:6457 dispatchDiscreteEvent @ react-dom.development.js:6430 VM60:1 Uncaught (in promise) SyntaxError: Unexpected token '<', "<html> <he"... is not valid JSON await (async) loadPyodide @ pyodide.js:215 loadPyodide @ App.js:12 runPythonScript @ App.js:24 callPython @ App.js:59 await in callPython (async) callCallback @ react-dom.development.js:4164 invokeGuardedCallbackDev @ react-dom.development.js:4213 invokeGuardedCallback @ react-dom.development.js:4277 invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291 executeDispatch @ react-dom.development.js:9041 processDispatchQueueItemsInOrder @ react-dom.development.js:9073 processDispatchQueue @ react-dom.development.js:9086 dispatchEventsForPlugins @ react-dom.development.js:9097 (anonymous) @ react-dom.development.js:9288 batchedUpdates$1 @ react-dom.development.js:26140 batchedUpdates @ react-dom.development.js:3991 dispatchEventForPluginEventSystem @ react-dom.development.js:9287 dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465 dispatchEvent @ react-dom.development.js:6457 dispatchDiscreteEvent @ react-dom.development.js:6430 pyodide.asm.js:10 Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'tests') at pyodide.asm.js:10:114344 at loadPyodide (pyodide.js:227:9) at async loadPyodide (App.js:16:1) at async runPythonScript (App.js:24:1) at async callPython (App.js:59:1)
解决后的代码
参考示例修改代码后,已能正常运行,以下是包含numpy和OpenCV导入的可运行示例:
import React, { useEffect, useState } from "react"; import {useScript} from 'usehooks-ts' const App = () => { const pyodideStatus = useScript("https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js", { removeOnUnmount: false, }) const [pyodide, setPyodide] = useState(null); const [pyodideLoaded, setPyodideLoaded] = useState(false); useEffect(() => { if (pyodideStatus === "ready") { setTimeout(()=>{ (async function () { const indexUrl = `https://cdn.jsdelivr.net/pyodide/v0.21.2/full/` const pyodide = await globalThis.loadPyodide({indexUrl}); setPyodide(pyodide); await pyodide.loadPackage(["numpy","opencv-python"]); setPyodideLoaded(true); })(); }, 1000) } }, [pyodideStatus]); async function callThis() { const myPython = ` import numpy as np import cv2 def func(): return np.array2string(5*np.array((1,2,3)))+" | numpy version: "+np.__version__+" | opencv version: "+cv2.__version__ func() `; if (pyodideLoaded) { console.log(pyodide); let element = document.getElementById("replace"); element.innerHTML = pyodide.runPython(myPython); console.log(element.innerHTML) } else { console.log("Pyodide not loaded yet"); } } return ( <div> <div id="replace">Replace this</div> <button onClick={callThis}> Execute Python </button> </div> ); }; export default App;
内容的提问来源于stack exchange,提问作者GaryK
相关产品推荐
相关产品推荐

