🍈最近工作中需要使用brython来执行python文件,记录下js 中调用python声明的函数
🍈Brython: Calling Methods of objects from a seperate python file
🍉brython的官网:brython.info/
🍉项目github:github.com/froggogo/re…
tip:首先最重要的加载 brython.js 和brython_stdlib.js
useEffect(() => {
// 加载 Brython 库
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/brython@3.11.2/brython.min.js';
document.body.appendChild(script);
const brythonStdLib = document.createElement('script');
brythonStdLib.src = 'https://cdn.jsdelivr.net/npm/brython@3.11.2/brython_stdlib.js';
document.body.appendChild(brythonStdLib);
script.onload = () => {
console.log('[---script.onload---]');
// 加载 Brython 脚本
loadBrythonCode()
return () => {
// 清理工作
if (script.parentNode) script.parentNode.removeChild(script);
if (brythonStdLib.parentNode) brythonStdLib.parentNode.removeChild(brythonStdLib);
};
}
}, []);
python代码放在public中
from browser import window
class MyPythonClass:
def __init__(self, name = ''):
self.name = name
def greet(self,name):
print(f"Hello, {name}!")
return f"Hello from {self}!"
window.MyPythonClass = MyPythonClass()
加载brython库完成之后,拿到python文件的内容,并执行brython解析python脚本
🍅window.brython() 是 Brython 库中的一个核心函数,用于触发 Python 代码的解析和执行。
🍅我们可以拿到python 声明的类,传递给python 这样可以解决python 中self的问题
🍅核心代码: MyPythonClass.class.greet(MyPythonClass,messageToPass)
const loadBrythonCode = async () => {
try {
const response = await fetch('/python/print.py');
const code = await response.text();
// setPythonCode(code); // 动态加载的 Python 代码
if (window.brython) {
console.log('[执行 Python 代码]');
const scriptTag = document.createElement('script');
scriptTag.type = 'text/python';
scriptTag.innerHTML = code;
brythonContainer.current.innerHTML = code;
document.body.appendChild(scriptTag);
window.brython();
// 触发 Brython 解析脚本
await checkRuntime()
MyPythonClass.__class__.greet(MyPythonClass,messageToPass)
}
} catch (err) {
throw err;
}
};
我们要确保加载python 检查 window 对象上是否存在 MyPythonClass 属性
// 加载 Python 代码
const checkRuntime = () => {
return new Promise((resolve, reject) => {
let elapsedTime = 0;
const checkInterval = 50; // 检查频率(毫秒)
const timeout = 5000; // 5秒超时
// 立即首次检查
if (window.MyPythonClass) {
resolve(window.MyPythonClass);
return;
}
const interval = setInterval(() => {
elapsedTime += checkInterval;
// 超时拒绝
if (elapsedTime >= timeout) {
clearInterval(interval);
reject(new Error("Timeout: window.runtime not available after 5 seconds"));
return;
}
// 成功检测到 runtime
if (window.MyPythonClass) {
clearInterval(interval);
resolve(window.MyPythonClass);
}
}, checkInterval);
});
};
这样就可以react 中全局调用python定义的类调用它的方法, 我们把声明的传给python 就可以解决self 的问题
参考案例 # Brython: Calling Methods of objects from a seperate python file