在 Python 中,PyExecJS
是一个类似于 Ruby ExecJS 的库,它允许 Python 程序执行 JavaScript 代码。以下是详细的 PyExecJS 教程。
1. 安装 PyExecJS
首先安装 PyExecJS:
pip install PyExecJS
或者使用 pipenv:
pipenv install PyExecJS
2. 选择 JavaScript 运行时
PyExecJS 需要依赖一个 JavaScript 运行时环境。支持的运行时包括:
- Node.js (推荐)
- PhantomJS
- Nashorn (Java 8+)
- JavaScriptCore (macOS 自带)
- Windows Script Host (Windows 自带)
推荐安装 Node.js 作为运行时:
- 下载并安装 Node.js: https://nodejs.org/
- 验证安装:
node -v
和npm -v
3. 基本用法
3.1 检查可用运行时
import execjs
print(execjs.get().name) # 查看当前使用的运行时
print(execjs.available_runtimes()) # 查看所有可用运行时
3.2 执行简单的 JavaScript 代码
# 创建一个 JavaScript 环境
ctx = execjs.compile("""
function add(a, b) {
return a + b;
}
""")
# 调用 JavaScript 函数
result = ctx.call("add", 1, 2)
print(result) # 输出: 3
3.3 直接执行 JavaScript 代码片段
result = execjs.eval("'Hello ' + 'World'")
print(result) # 输出: Hello World
4. 高级用法
4.1 使用外部 JavaScript 文件
假设有一个 math.js
文件:
// math.js
function square(n) { return n * n; }
function cube(n) { return n * n * n; }
在 Python 中使用:
with open('math.js', 'r') as f:
js_code = f.read()
ctx = execjs.compile(js_code)
print(ctx.call("square", 4)) # 输出: 16
print(ctx.call("cube", 3)) # 输出: 27
4.2 处理 JavaScript 对象
ctx = execjs.compile("""
var person = {
name: "John",
age: 30,
greet: function() {
return "My name is " + this.name + " and I'm " + this.age + " years old.";
}
};
""")
print(ctx.eval("person.name")) # 输出: John
print(ctx.eval("person.greet()")) # 输出: My name is John and I'm 30 years old.
4.3 错误处理
try:
execjs.eval("thisFunctionDoesNotExist()")
except execjs.RuntimeError as e:
print(f"JavaScript 错误: {e}")
5. 实际应用示例
5.1 调用 npm 库
假设你安装了 lodash
:
npm install lodash
然后在 Python 中使用:
ctx = execjs.compile("""
var _ = require('lodash');
function chunk(array, size) {
return _.chunk(array, size);
}
""")
result = ctx.call("chunk", [1, 2, 3, 4, 5], 2)
print(result) # 输出: [[1, 2], [3, 4], [5]]
5.2 处理 JSON 数据
ctx = execjs.compile("""
function parseJSON(jsonStr) {
return JSON.parse(jsonStr);
}
function stringifyJSON(obj) {
return JSON.stringify(obj);
}
""")
# 解析 JSON
json_obj = ctx.call("parseJSON", '{"name": "John", "age": 30}')
print(json_obj) # 输出: {'name': 'John', 'age': 30}
# 生成 JSON
json_str = ctx.call("stringifyJSON", {"name": "John", "age": 30})
print(json_str) # 输出: {"name":"John","age":30}
6. 性能优化
对于频繁执行的 JavaScript 代码,可以预编译以提高性能:
# 预编译 JavaScript 代码
precompiled = execjs.compile("""
function complexCalculation(x) {
// 复杂的计算逻辑
return x * x + 2 * x + 1;
}
""")
# 多次调用
for i in range(1000):
result = precompiled.call("complexCalculation", i)