全面接纳Node.js:Python的JSPyBridge即将大热?

发表时间: 2023-10-13 06:20

家好,很高兴又见面了,我是"高级前端‬进阶‬",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。

什么是 JSPyBridge

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 上开源,是一个值得关注的前端开源项目

如何使用 JSPyBridge

从 Python 访问 JavaScript

from javascript import require, globalThischalk, 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';// 导入 tkinterconst 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/