【问题标题】:Call python function from node.js从 node.js 调用 python 函数
【发布时间】:2018-05-01 09:15:00
【问题描述】:
我想从 node.js 调用 python 函数。我找到了python-shell。但据我了解,它只能运行一个完整的 python 脚本。
我有一些逻辑(加载一个大文件)大约需要 2 分钟。我想运行它,然后从节点调用 python 函数,以便文件只加载一次。
# load a huge file takes 2min
model = xyz.load(path)
# function using that model
def doSomething(id):
# some logic using the model
return model.get(id)
如何重复调用doSomething()而不每次都加载文件?
【问题讨论】:
标签:
python
node.js
node-modules
【解决方案1】:
理论上可以将 Python 解释器加载到另一个进程中,然后与之交互,但如果还没有它的包,这并不容易。你可能已经检查过了。
如果可能的话,事先弄清楚你需要在 Python 中做的所有事情,将一个列表传递给脚本,然后将结果作为一个列表返回给 Node.js。这样你只需要运行一次脚本。
如果这不可行,您可以将 Python 脚本作为一个单独的进程启动,并让您的 Node.js 程序使用某种协议与它通信,也许像 JSON 在 stdin/stdout 上一样简单。然后您的 Node.js 程序可以向 Python 程序发送命令,Python 程序可以回复结果。
【解决方案2】:
使用一些中间件,例如 ZeroMQ。它基本上使套接字变得简单(发送的原子单元是整个消息,而不是数据包)。它适用于node.js 和python。
典型的 REQ/REP 客户端/服务器只有几行代码。
例如:python 服务器:
import time
import zmq
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:5555")
while True:
# Wait for next request from client
message = socket.recv()
print("Received request: %s" % message)
# Do some 'work'
time.sleep(1)
# Send reply back to client
socket.send(b"World")
和 node.js 客户端:
var zmq = require('zmq');
// socket to talk to server
console.log("Connecting to hello world server…");
var requester = zmq.socket('req');
var x = 0;
requester.on("message", function(reply) {
console.log("Received reply", x, ": [", reply.toString(), ']');
x += 1;
if (x === 10) {
requester.close();
process.exit(0);
}
});
requester.connect("tcp://localhost:5555");
for (var i = 0; i < 10; i++) {
console.log("Sending request", i, '…');
requester.send("Hello");
}
process.on('SIGINT', function() {
requester.close();
});
【解决方案3】:
原来有一个使用 python-shell 的解决方案。详情可见here。