Brython 在react中使用 python声明的类并调用类的方法,并解决self

111 阅读1分钟
🍈最近工作中需要使用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中

python代码.png
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