如何从 Node.js 调用 Python 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23450534/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to call a Python function from Node.js
提问by Genjuro
I have an Express Node.js application, but I also have a machine learning algorithm to use in Python. Is there a way I can call Python functions from my Node.js application to make use of the power of machine learning libraries?
我有一个 Express Node.js 应用程序,但我也有一个在 Python 中使用的机器学习算法。有没有一种方法可以从我的 Node.js 应用程序调用 Python 函数来利用机器学习库的强大功能?
回答by NeverForgetY2K
Easiest way I know of is to use "child_process" package which comes packaged with node.
我所知道的最简单的方法是使用 node.js 打包的“child_process”包。
Then you can do something like:
然后你可以做这样的事情:
const spawn = require("child_process").spawn;
const pythonProcess = spawn('python',["path/to/script.py", arg1, arg2, ...]);
Then all you have to do is make sure that you import sys
in your python script, and then you can access arg1
using sys.argv[1]
, arg2
using sys.argv[2]
, and so on.
然后你所要做的就是确保你import sys
在你的 python 脚本中,然后你可以访问arg1
using sys.argv[1]
,arg2
using sys.argv[2]
,等等。
To send data back to node just do the following in the python script:
要将数据发送回节点,只需在 python 脚本中执行以下操作:
print(dataToSendBack)
sys.stdout.flush()
And then node can listen for data using:
然后节点可以使用以下方法侦听数据:
pythonProcess.stdout.on('data', (data) => {
// Do something with the data returned from python script
});
Since this allows multiple arguments to be passed to a script using spawn, you can restructure a python script so that one of the arguments decides which function to call, and the other argument gets passed to that function, etc.
由于这允许使用 spawn 将多个参数传递给脚本,因此您可以重构 python 脚本,以便其中一个参数决定调用哪个函数,另一个参数传递给该函数,等等。
Hope this was clear. Let me know if something needs clarification.
希望这很清楚。如果有什么需要澄清的,请告诉我。
回答by Amit Upadhyay
Examplefor people who are from Python background and want to integrate their machine learning model in the Node.js application:
对于具有 Python 背景并希望将他们的机器学习模型集成到 Node.js 应用程序的人员的示例:
It uses the child_process
core module:
它使用child_process
核心模块:
const express = require('express')
const app = express()
app.get('/', (req, res) => {
const { spawn } = require('child_process');
const pyProg = spawn('python', ['./../pypy.py']);
pyProg.stdout.on('data', function(data) {
console.log(data.toString());
res.write(data);
res.end('end');
});
})
app.listen(4000, () => console.log('Application listening on port 4000!'))
It doesn't require sys
module in your Python script.
它不需要sys
您的 Python 脚本中的模块。
Below is a more modular way of performing the task using Promise
:
以下是使用以下命令执行任务的更模块化的方式Promise
:
const express = require('express')
const app = express()
let runPy = new Promise(function(success, nosuccess) {
const { spawn } = require('child_process');
const pyprog = spawn('python', ['./../pypy.py']);
pyprog.stdout.on('data', function(data) {
success(data);
});
pyprog.stderr.on('data', (data) => {
nosuccess(data);
});
});
app.get('/', (req, res) => {
res.write('welcome\n');
runPy.then(function(fromRunpy) {
console.log(fromRunpy.toString());
res.end(fromRunpy);
});
})
app.listen(4000, () => console.log('Application listening on port 4000!'))
回答by Soumik Rakshit
The python-shell
module by extrabacon
is a simple way to run Python scripts from Node.js with basic, but efficient inter-process communication and better error handling.
在python-shell
通过模块extrabacon
是一个简单的方法来基本运行Node.js的从Python脚本,但高效的进程间通信和更好的错误处理。
Installation:npm install python-shell
.
安装:npm install python-shell
。
Running a simple Python script:
运行一个简单的 Python 脚本:
var PythonShell = require('python-shell');
PythonShell.run('my_script.py', function (err) {
if (err) throw err;
console.log('finished');
});
Running a Python script with arguments and options:
运行带有参数和选项的 Python 脚本:
var PythonShell = require('python-shell');
var options = {
mode: 'text',
pythonPath: 'path/to/python',
pythonOptions: ['-u'],
scriptPath: 'path/to/my/scripts',
args: ['value1', 'value2', 'value3']
};
PythonShell.run('my_script.py', options, function (err, results) {
if (err)
throw err;
// Results is an array consisting of messages collected during execution
console.log('results: %j', results);
});
For the full documentation and source code, check out https://github.com/extrabacon/python-shell
有关完整的文档和源代码,请查看https://github.com/extrabacon/python-shell
回答by 1mike12
I'm on node 10 and child process 1.0.2
. The data from python is a byte array and has to be converted. Just another quick example of making a http request in python.
我在 node 10 和 child process 上1.0.2
。来自python的数据是一个字节数组,必须进行转换。这是在 python 中发出 http 请求的另一个快速示例。
node
节点
const process = spawn("python", ["services/request.py", "https://www.google.com"])
return new Promise((resolve, reject) =>{
process.stdout.on("data", data =>{
resolve(data.toString()); // <------------ by default converts to utf-8
})
process.stderr.on("data", reject)
})
request.py
请求文件
import urllib.request
import sys
def karl_morrison_is_a_pedant():
response = urllib.request.urlopen(sys.argv[1])
html = response.read()
print(html)
sys.stdout.flush()
karl_morrison_is_a_pedant()
p.s. not a contrived example since node's http module doesn't load a few requests I need to make
ps 不是一个人为的例子,因为节点的 http 模块没有加载我需要发出的一些请求
回答by Jonathan
回答by bormat
Most of previous answers call the success of the promise in the on("data"), it is not the proper way to do it because if you receive a lot of data you will only get the first part. Instead you have to do it on the end event.
以前的大多数答案都将 on("data") 中的承诺称为成功,这不是正确的做法,因为如果您收到大量数据,您将只能获得第一部分。相反,您必须在结束事件中执行此操作。
const { spawn } = require('child_process');
const pythonDir = (__dirname + "/../pythonCode/"); // Path of python script folder
const python = pythonDir + "pythonEnv/bin/python"; // Path of the Python interpreter
/** remove warning that you don't care about */
function cleanWarning(error) {
return error.replace(/Detector is not able to detect the language reliably.\n/g,"");
}
function callPython(scriptName, args) {
return new Promise(function(success, reject) {
const script = pythonDir + scriptName;
const pyArgs = [script, JSON.stringify(args) ]
const pyprog = spawn(python, pyArgs );
let result = "";
let resultError = "";
pyprog.stdout.on('data', function(data) {
result += data.toString();
});
pyprog.stderr.on('data', (data) => {
resultError += cleanWarning(data.toString());
});
pyprog.stdout.on("end", function(){
if(resultError == "") {
success(JSON.parse(result));
}else{
console.error(`Python error, you can reproduce the error with: \n${python} ${script} ${pyArgs.join(" ")}`);
const error = new Error(resultError);
console.error(error);
reject(resultError);
}
})
});
}
module.exports.callPython = callPython;
Call:
称呼:
const pythonCaller = require("../core/pythonCaller");
const result = await pythonCaller.callPython("preprocessorSentiment.py", {"thekeyYouwant": value});
python:
Python:
try:
argu = json.loads(sys.argv[1])
except:
raise Exception("error while loading argument")
回答by Geordie
You can now use RPC libraries that support Python and Javascript such as zerorpc
您现在可以使用支持 Python 和 Javascript 的 RPC 库,例如zerorpc
From their front page:
从他们的首页:
Node.js Client
Node.js 客户端
var zerorpc = require("zerorpc");
var client = new zerorpc.Client();
client.connect("tcp://127.0.0.1:4242");
client.invoke("hello", "RPC", function(error, res, more) {
console.log(res);
});
Python Server
蟒蛇服务器
import zerorpc
class HelloRPC(object):
def hello(self, name):
return "Hello, %s" % name
s = zerorpc.Server(HelloRPC())
s.bind("tcp://0.0.0.0:4242")
s.run()