如何通过Node.js和child_process模块实现JavaScript调用Python脚本进行机器学习开发
最近在进行一个项目,其中可能包含机器学习部分。同伴选择用 python 来实现机器学习算法。因为这是一个基于 web 的应用,所以能够完全用 python 来完成 web 应用开发以及机器学习的实现。然而,由于对 Dijango 了解较少,熟练度比不上 Nodejs。打算通过混合编程的方式,实现在 JavaScript 代码里调用 Python 脚本。

Nodejs必要模块child_process
实现原理较为简单。通过使用 child_process 这个模块,能够帮助开发者在 nodejs 环境里构建一个子进程。接着,在这个子进程中利用系统命令行来运行 python 脚本,例如 python test_py.py arg0 arg1,以此实现对 python 脚本的调用。
[id_1836809070]
child_process 是一个重要模块,用于生成子进程。它具备调用子进程的方法,还能传递参数给子进程。其重要的属性和函数可参考官方的 API。
我们在讲解完 child_process 之后开始进行测试。首先,我们来写一个简单的 Python 测试脚本 test_py.py,其代码如下:
#encode:utf-8
import sys
for i in range(len(sys.argv)):
print('arg'+str(i),sys.argv[i])
上述代码的功能是打印通过命令行运行 python 脚本代码时所传递的参数,并且在 python 脚本中使用了 sys 模块。这个模块中的 argv 属性是一个列表。它用于存放使用系统命令行运行 python 脚本时传入的参数以及脚本文件的名称。其中,argv 的第一个值是脚本名称,从第二个值开始才是命令行传入的参数。上述代码的运行效果如下:
在 nodejs 里要实现调用这个脚本,相应的 JavaScript 代码是这样的:
var exec = require('child_process').exec;
var arg1 = 'hello';
var arg2 = 'world';
var filename = 'test_py.py'
exec('python'+' '+filename+' '+arg1+' '+arg2,function(err,stdout,stderr){
if(err)
{
console.log('stderr',err);
}
if(stdout)
{
console.log('stdout',stdout);
}
});
最后在命令行下执行的结果为:
我们可以看到,python 脚本输出到控制台的内容,在 nodejs 的程序里被进行了完全的解析,并且被解析为了字符串,这些字符串被存放在了回调函数的输入参数 stdout 中。如果我们需要实现 nodejs 脚本调用 python 脚本并获取其输出结果,那么可以在 python 脚本中打印计算结果,接着在 nodejs 脚本中对这个打印出的字符串进行解析。
在 javascript 中处理的对象大多是 JSON。所以要达成友好的两种脚本语言交互,可在 python 中先把要交互的内容生成 json 字符串,接着用 print 进行打印输出。而 javascript 代码获取此字符串后,能够直接进行 json 对象转换。实例如下:
首先是 Python 代码,它能够把 json 对象转换为字符串,然后将这个字符串输出到控制台。
import json # import the module of json
import sys 这个模块被用于从命令行获取参数。
params = sys.argv[1]
obj = json.loads(params) #str to obj
jsonob = {'name':'alex','age':18,'gender':'male'}
strjson 等于 json.dumps(jsonob,排序键为 True),即按照键的顺序对 jsonob 进行序列化并转换为字符串。这样可以确保在序列化过程中,字典的键以特定的顺序排列,使得生成的 JSON 字符串具有一致性。通过设置 sort_keys=True,无论原始字典的键顺序如何,序列化后的 JSON 字符串中的键都会按照字母顺序排列。这种方式在需要比较或处理多个 JSON 字符串时非常有用,因为它可以确保它们具有相同的结构和顺序。True)
print(strjson)
python 代码会接收来自命令行的参数,接着它会输出一个对应的字符串,这个字符串是一个 json 对象。
2. 然后使用合适的 javascript 方法将该字符串转换为 json 对象。
var exec = require('child_process').exec;
filename = 'test_pyjson.py'
var editor={
"name":'alex',
"age":18,
"address":'fghjh'
};
var str = 该对象的名称是 alex,年龄为 18,地址是 sdsdd。; 将 JavaScript 对象转换为 JSON 字符串。
exec('python '+filename+' '+str,function(err,stdout,stdin){
if(err){
console.log('err');
}
if(stdout)
{
//parse the string
console.log(stdout);
var astr = stdout.split('\r\n').join('');//delete the \r\n
var obj = JSON.parse(astr);
console.log('name',obj.name);
console.log('age',obj.age);
console.log('gender',obj.gender);
}
});
执行javascript代码:
可以看到,javascript 成功地解析了 Python 代码执行的命令行输出结果,并且实现了 javascript 与 python 的混编。
nodejs 调用脚本与其他脚本交互时主要有三步。首先,在 javascript 代码中利用 child_process 模块来创建子进程。其次,子进程调用命令行并传递参数,以此完成对其他语言脚本代码的调用。最后,根据其他语言控制台输出的字符串进行 JSON 格式的解析,从而完成了 Nodejs 与其他脚本语言的交互过程。