从 node.js 调用 python 函数

Call python function from node.js

我想从 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 解释器加载到另一个进程中,然后与之交互,但如果没有用于它已经。您可能已经检查过了。

如果可能的话,事先在 Python 中弄清楚你需要做的所有事情,将列表传递给脚本,然后 return 结果作为列表返回给 Node.js.这样你只需要 运行 脚本一次。

如果那不可能,您可以将 Python 脚本作为一个单独的进程启动,并让您的 Node.js 程序使用某种协议与它通信,可能像 JSON 这样简单的协议超过 stdin/stdout。然后您的 Node.js 程序可以向 Python 程序发送命令并且 Python 程序可以回复结果。

使用一些像 ZeroMQ 这样的中间件。它基本上是简单的套接字(发送的原子单元是整个 消息 ,而不是数据包)。它适用于 node.js and python.

典型的REQ/REP client/server只有几行。

例如: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();
});

事实证明,使用 python-shell 可以解决此问题。详情可见.