杰瑞科技汇

Python如何调用JavaScript引擎?

为什么需要 Python 中的 JavaScript 引擎?

想象一下以下常见场景:

Python如何调用JavaScript引擎?-图1
(图片来源网络,侵删)
  1. 前端自动化测试:你的后端服务是用 Python (Django/Flask) 编写的,但你需要运行使用 Cypress、Playwright 或 Puppeteer 等工具编写的端到端 (E2E) 测试,这些工具本质上是 Node.js 应用,但你可以通过 Python 脚本来触发和管理它们。
  2. 执行前端代码:你有一个由 JavaScript 生成或处理的数据(一个复杂的可视化图表配置),你想在 Python 后端执行这段 JS 代码来生成最终的 HTML 或数据,而无需启动一个完整的 Node.js 环境。
  3. 利用现有的 JS 库:某个强大的库只有 JavaScript 版本(一些图像处理、科学计算或特定的 Web API 库),你可以通过 Python 来调用它,而不是用 Python 重新实现一遍。
  4. 服务器端渲染 (SSR):在 Python Web 框架中,集成一个 React 或 Vue 应用,在服务器端渲染页面,然后将 HTML 发送给客户端。

为了实现这些,我们需要一个在 Python 中运行 JavaScript 代码的“桥梁”,这个桥梁就是 JavaScript 引擎


主流 Python JavaScript 引擎推荐

有几个非常优秀的库可以让你在 Python 中运行 JavaScript,它们各有侧重,适用于不同的场景。

PyMiniRacer (推荐用于高性能场景)

PyMiniRacer 是一个高性能的 JavaScript 引擎,它将 Google 的 V8 引擎(也就是 Chrome 和 Node.js 使用的核心)编译成一个 Python 扩展。

  • 核心:Google V8
  • 优点
    • 性能极高:因为它直接使用了 V8,所以执行 JS 代码的速度非常快,接近原生 Node.js。
    • 内存效率高:V8 引擎被编译成一个单独的库,与 Python 进程共享内存,开销相对较小。
    • 功能完整:支持最新的 ECMAScript (JavaScript) 标准。
  • 缺点
    • 安装复杂:需要编译 C++ 扩展,在某些系统(特别是 Windows 或没有编译工具链的 Linux 环境)上安装可能会遇到困难。
    • 不是纯 Python:它是一个 C 扩展,依赖于系统环境。
  • 适用场景
    • 需要在 Python 中大量、频繁地执行 JS 代码。
    • 对性能要求苛刻的场景,例如处理复杂的 JS 算法或数据转换。

安装

Python如何调用JavaScript引擎?-图2
(图片来源网络,侵删)
# 可能需要先安装 build-essential (Debian/Ubuntu) 或 Xcode Command Line Tools (macOS)
pip install py_mini_racer

示例代码

from py_mini_racer import JSException, MiniRacer
# 创建一个 JS 运行时环境
ctx = MiniRacer()
# 执行简单的 JS 代码
print(ctx.execute("1 + 2"))  # 输出: 3
# 调用 JS 函数
js_code = """
(function add(a, b) {
    return a + b;
})
"""
ctx.eval(js_code)
print(ctx.call("add", 10, 20))  # 输出: 30
# 在 JS 和 Python 之间传递复杂数据(JSON 格式)
data = {"name": "Alice", "age": 30, "skills": ["Python", "JS"]}
# 将 Python 字典转为 JSON 字符串传给 JS
json_data = ctx.execute(f"JSON.stringify({data})")
print(json_data)  # 输出: {"name":"Alice","age":30,"skills":["Python","JS"]}
# 从 JS 接收数据并转为 Python 字典
js_result = ctx.execute("JSON.parse('{\"city\": \"New York\"}')")
print(js_result)  # 输出: {'city': 'New York'}
print(type(js_result)) # 输出: <class 'dict'>

PyExecJS (通用型,易于使用)

PyExecJS 是一个更通用的库,它不直接包含 JS 引擎,而是作为适配器,让你可以方便地在多种不同的 JS 运行时之间切换。

  • 核心:适配器模式,支持 Node.js, PyV8, PhantomJS, JavaScriptCore 等。
  • 优点
    • 安装极其简单pip install PyExecJS,无需编译。
    • 通用性强:如果系统已经安装了 Node.js,它会自动使用它,非常方便。
    • 跨平台性好:只要有可用的后端 JS 环境,就能运行。
  • 缺点
    • 性能依赖于后端:如果使用 Node.js 作为后端,性能不错,但启动一个新的 Node.js 进程会有一定的开销,不适合高频调用。
    • 不是引擎本身:它是一个“指挥官”,性能上限取决于它指挥的“士兵”(哪个 JS 引擎)。
  • 适用场景
    • 快速原型开发。
    • 系统已经安装了 Node.js,希望简单地在 Python 中调用 JS。
    • 不关心底层引擎,只希望代码能运行起来。

安装

pip install PyExecJS

示例代码

Python如何调用JavaScript引擎?-图3
(图片来源网络,侵删)
import execjs
# PyExecJS 会自动在系统中寻找可用的 JS 运行时
# 如果你安装了 Node.js,它会默认使用它
# 执行 JS 代码
ctx = execjs.compile("""
    function add(a, b) {
        return a + b;
    }
    function greet(name) {
        return 'Hello, ' + name + '!';
    }
""")
# 调用函数
print(ctx.call("add", 5, 7))  # 输出: 12
print(ctx.call("greet", "World")) # 输出: Hello, World!

Transcrypt (将 Python 代码编译成 JavaScript)

Transcrypt 的思路与前两者完全不同,它不是一个在 Python 中“运行”JS 的引擎,而是一个编译器,它允许你使用 Python 的语法和库来编写代码,然后将其编译成能在浏览器或 Node.js 中运行的 JavaScript。

  • 核心:Python 到 JavaScript 的编译器。
  • 优点
    • 语言统一:你可以用 Python 的思维和生态(部分库)来开发前端代码。
    • 类型检查:编译时可以发现一些错误。
    • 代码复用:理论上,一些核心业务逻辑可以在 Python 后端和 JavaScript 前端之间共享。
  • 缺点
    • 不是运行时:它不能让你在 Python 脚本中动态执行一段 JS 字符串。
    • 不是 100% Python:不是所有的 Python 库和语法都能被支持,你需要使用 Transcrypt 兼容的子集。
    • 学习成本:你需要理解它的工作方式和限制。
  • 适用场景
    • 想用 Python 语言开发纯前端应用(WebAssembly 的一个替代方案)。
    • 希望在前后端共享大量 Python 代码逻辑。

安装与使用

pip install transcrypt
# 创建一个 Python 模块,mymodule.py
# transcrypt -b -k mymodule
# 这会生成 JS 文件,可以在浏览器中运行

特性 PyMiniRacer PyExecJS Transcrypt
核心思想 在 Python 中嵌入 V8 引擎 Python 调用外部 JS 运行时的适配器 将 Python 代码编译成 JS
性能 非常高 (接近原生) 中等 (依赖后端,如 Node.js) 编译后性能好,但非运行时性能
安装难度 较高 (需编译) 非常简单 简单
跨平台性 一般 (依赖编译环境) 非常好 (只要有后端引擎)
主要用途 高性能 JS 代码执行 通用 JS 代码调用、快速原型 用 Python 编写前端/JS 代码
与 Python 交互 直接传递 Python 对象 通过 JSON 字符串交互 编译时确定,无运行时交互

如何选择?

  • 追求极致性能,且不介意安装的复杂性选择 PyMiniRacer,它是目前 Python 执行 JS 代码性能的标杆。
  • 快速验证想法、系统已有 Node.js、或希望安装过程丝滑无阻选择 PyExecJS,它是最简单、最通用的选择。
  • 想用 Python 语言为浏览器或 Node.js 编写代码,实现前后端语言统一选择 Transcrypt,它是一个编译工具,而不是运行
分享:
扫描分享到社交APP
上一篇
下一篇