在现代软件开发中,我们经常需要将不同的编程语言和技术栈结合起来,以利用各自的优势。Node.js以其在处理I/O密集型任务和构建快速、可扩展的网络应用方面的卓越性能而闻名。而Python则以其简洁的语法和强大的数据处理能力而受到数据科学家和开发者的青睐。在某些情况下,我们可能需要在Node.js环境中调用Python代码,或者反过来。node-pyrunner
模块正是为了实现这一目标而设计的。
什么是node-pyrunner?
node-pyrunner
是一个Node.js的npm模块,它允许JavaScript与Python之间的直接交互。通过使用node-pyrunner
,我们可以在Node.js应用中同步或异步地执行Python代码,同时也可以利用Python来执行JavaScript代码。这种交互是通过底层的v8引擎与Python直接通信实现的,从而避免了创建新进程的开销,提高了执行效率。
node-pyrunner的主要优点
- 无需创建新进程:直接在Node.js环境中嵌入Python,减少了资源消耗。
- 异步编程支持:可以在Python中引入异步编程,提高程序的响应性和吞吐量。
- 虚拟环境支持:可以在Python虚拟环境中运行代码,避免了全局环境的污染。
- 跨语言执行:Python中可以执行JavaScript脚本,反之亦然,极大地扩展了两者的应用范围。
如何使用node-pyrunner
安装
首先,你需要通过npm安装node-pyrunner
模块:
bash
npm install node-pyrunner
基本使用
在Node.js应用中,你可以按照以下步骤使用node-pyrunner
:
- 引入模块:
javascript
const pyrunner = require('node-pyrunner');
- 配置和初始化:
javascript
// 配置初始化信息
pyrunner.config['python_home'] = './python/win32/x64/3.10.10';
pyrunner.config['module_search_paths'][0] = './pyscript';
pyrunner.init(); // 初始化
在这段代码中:
javascript
pyrunner.config['python_home'] = './python/win32/x64/3.10.10';
'./python/win32/x64/3.10.10'
是一个路径,它指定了Python解释器的安装位置。这个路径告诉node-pyrunner
模块在哪里可以找到Python的可执行文件(例如python.exe
),以便在Node.js环境中启动和运行Python代码。
这里的路径结构说明如下:
./
:表示当前工作目录的相对路径。python/
:是一个文件夹,通常用于存放特定版本的Python解释器。win32/
:表示这个路径是为Windows操作系统准备的。x64/
:表示这个路径下的Python解释器是为64位系统编译的。3.10.10
:是Python解释器的版本号,这里的3.10.10
指的是Python 3.10.10版本。
因此,当你运行这段代码时,node-pyrunner
会尝试在指定的路径下找到Python解释器,并使用它来执行Python代码。这意味着你需要在该路径下有一个有效的Python安装,否则node-pyrunner
将无法正常工作。
如果你的Python安装在不同的路径,或者你使用的是不同的操作系统(比如Linux或macOS),你需要相应地调整这个路径。例如,在Linux上,路径可能看起来像/usr/bin/python3.10
,在macOS上可能是/Library/Frameworks/Python.framework/Versions/3.10/bin/python3.10
。
- 执行Python脚本:
javascript
// 执行python脚本
pyrunner.runScriptSync("print('main runSync pyscript')");
pyrunner.runScript("print('main run pyscript')");
- 使用Python模块:
javascript
let appModule = pyrunner.import('app');
// 同步调用app.py的hello函数
appModule.callSync('hello', ['pyrunner']);
// 异步调用app.py的callJsFunc函数
appModule.call('callJsFunc', [1, 2], (data) => {
console.log(data);
}, (err) => {
console.log(err);
});
- Python调用JavaScript函数:
javascript
// python调用的JS函数,必须是函数名=函数体,表示该函数在global对象之下,否则python无法调用
let sayHello = function (num1, num2) {
let total = num1 + num2;
return ++total;
}
示例:系统资源监视器
node-pyrunner
可以用于构建复杂的应用,例如系统资源监视器。在这个示例中,我们使用Electron作为图形界面,通过node-pyrunner
执行Python脚本,实现了CPU和内存使用情况的实时监控。Python部分使用psutil
库获取系统信息,并通过调用JavaScript函数更新Echarts图表来展示数据。
Python代码(app.py)
python
import nodepyrunner
import threading
import time
import psutil
import winreg
import json
def cpu_info():
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"HARDWARE\DESCRIPTION\System\CentralProcessor\0")
cpu_name = winreg.QueryValueEx(key, "ProcessorNameString")
key.Close()
data = dict(
cpu_name=cpu_name[0],
cpu_avg=psutil.cpu_percent(interval=0, percpu=False),
per_cpu_avg=psutil.cpu_percent(interval=0, percpu=True),
cpu_core=psutil.cpu_count(False),
cpu_logic=psutil.cpu_count(True)
)
return data
def cpu_monitor():
while(True):
time.sleep(1)
data = cpu_info()
j_str = json.dumps(data)
nodepyrunner.callJs(target='UpdateCPU', args=[j_str])
def start():
t_cpu = threading.Thread(target=cpu_monitor, args=())
t_cpu.start()
JavaScript代码(renderer.js)
javascript
const pyrunner = require('node-pyrunner')
pyrunner.config['module_search_paths'].push('./pyscript');
pyrunner.init();
let appModule = pyrunner.import('app');
appModule.callSync('start', []); //启动python监视线程
function UpdateCPU(jsonStr) {
let obj = JSON.parse(jsonStr);
// 更新图表数据
// ...
}
通过这个示例,我们可以看到node-pyrunner
如何将Node.js和Python的强大功能结合起来,创建一个功能丰富的桌面应用。这种跨语言的交互为开发者提供了更多的灵活性和可能性,使得我们可以在同一个项目中利用两种语言的优势。
注意
node-pyrunner模块是一个允许Node.js调用Python代码的npm模块。根据搜索结果,node-pyrunner模块支持的Python版本主要是Python 3.5及以上版本。
在某些情况下,Node.js可能需要与Python进行交互或调用Python的库,这就需要在安装Node.js时正确配置Python的环境。node-pyrunner模块通过嵌入Python实现了底层v8引擎与Python的直接通信,允许JavaScript同步或异步执行Python语句和调用Python函数。同时,在Python中也可以执行JavaScript语句和调用JavaScript的函数。
需要注意的是,虽然node-pyrunner模块支持Python 3.5及以上版本,但是为了确保最佳的兼容性和性能,建议使用较新的Python版本。同时,由于Node.js和Python都在持续更新,可能会有新的版本发布,因此在使用node-pyrunner模块时,建议关注其官方文档或GitHub仓库,以获取最新的支持信息和使用指南。