JSPyBridge 用于 Node.js 和 Python的互操作。开发者可以从 Node.js 运行 Python,或从 Python 运行 Node.js,目前该项目的深度研发工作正在陆续进行中。 如果需要体验,开发者需要安装 Node.js 14 和 Python 3.8 或更高版本。
JSPyBridge 的典型特征包括:
能够调用异步和同步函数并以原生方式获取对象属性
内置垃圾收集
具有任意参数的双向回调
迭代和异常处理支持
对象检查允许开发者轻松地 console.log 或 print() 任何对象
JS 调用 Python 的桥梁:Python 类的扩展和继承,可以参考文末 pytorch 和 tensorflow 示例。
从 Python 调用 JS 的桥梁:基于本机装饰器的事件发射器支持
从 Python 调用 JS 的桥梁:一流的 Jupyter Notebook/Google Colab 支持。
目前 JSPyBridge 在 Github 上开源,是一个值得关注的前端开源项目。
从 Python 访问 JavaScript
from javascript import require, globalThis
chalk, fs = require("chalk"), require("fs")
print("Hello", chalk.red("world!"), "it's", globalThis.Date().toLocaleString())
fs.writeFileSync("HelloWorld.txt", "hi!")
从 JavaScript 访问 Python
import { python } from 'pythonia';
// 导入 tkinter
const tk = await python('tkinter');
// 有Python API访问都必须以await为前缀
const root = await tk.Tk();
// 带 $ 后缀的函数调用会将最后一个参数视为 kwarg 字典
const a = await tk.Label$(root, { text: 'Hello World' });
await a.pack();
await root.mainloop();
python.exit();
//确保最后退出Python以允许Node退出,开发者还可以使用 process.exit
需要注意的是,JSPyBridge 与其他 Bridge 不同,开发者可能会注意到不只是用 JavaScript 编写 Python 代码,反之亦然。
开发者可以对 Bridge 另一侧的对象进行操作,就像这些对象存在于当前环境一样, 这是通过真正的互操作支持实现的。
开发者可以调用回调,并使用自己喜欢的任何参数进行无损函数调用,当然浮点精度除外。
同时,需要注意以下几点:
当进行函数调用时,任何外部对象都会作为引用传递。 例如,如果在 JavaScript 中对返回数组的 Python 进行函数调用,则不会返回 JS 数组,但会获得对 Python 数组的引用。 只要使用await,开发者仍然可以使用[]符号正常访问数组。 如果希望 JSPyBridge 将外部引用转换为本机引用,则可以通过在 Python 数组上调用 .valueOf() 来请求原始值。 这会给你一个 JS 数组。 反之亦然。
上述行为使得将数据从一个函数传输到另一个函数的速度非常快,从而避免昂贵转换。
回调和函数参数不存在上述行为。 桥接器将尝试序列化它可以序列化的内容,如果无法序列化某些内容,则会提供外部引用。 因此,如果传递一个 JS 对象,将获得一个 Python 字典,但如果该字典包含类似类的内容,将在其位置获得一个引用。
同时还需要注意以下几点:
ffid 关键字被保留,不能在变量名称、对象键或值中使用它,其用于内部跟踪对象。
在从 Python 调用JavaScript 的 Bridge 上,由于Python和跨平台IPC的限制,目前通过标准错误进行通信,这意味着JS标准错误中的JSON输出可能会干扰Bridge。 Windows 上的 python 也存在同样的问题。 但是,您不太可能遇到此问题。
开发者可以在导入库之前通过设置 NODE_BIN 或 PYTHON_BIN 环境变量来设置 Node.js/Python 二进制路径。 否则,Nodejs 和 python3 或 python 二进制文件将相对于 PATH 环境变量被调用。
函数调用将在 100000 毫秒后超时并抛出 BridgeException 错误。 开发者可以通过在环境变量中定义 REQ_TIMEOUT 的新值来覆盖该默认值。
https://github.com/extremeheat/JSPyBridge#jspybridge
https://blog.logrocket.com/exploring-jspybridge-library-python-javascript/
https://deventor.io/blog/node-js-vs-python/