如何执行Python脚本并检索Node.js中的输出(数据和错误)

本文概述

  • 1)使用第三方库
  • 2)使用内置的child_process模块
Node.js使用事件驱动的非阻塞I / O模型, 使其轻巧高效, 非常适合在分布式设备上运行的数据密集型实时应用程序, 但是很少有计算任务可供你使用Python如果你非常关注项目的速度。
但另一方面, 你可能仍想使用Node.js, 因此你需要学习如何从Node执行Python脚本。在这种情况下, 我们将介绍最基本的要点, 如如何执行Python脚本以及如何检索生成的输出(包括标准输出和错误输出)。
在继续本教程之前, 你需要执行python脚本。因此, 在本文中, 我们将使用以下python脚本(如果你手边没有任何脚本或想要测试, 可以使用它):
# script.py my_name = 'Carlos' my_age = 18 # not a lie my_height = 172 # cm my_weight = 71 # kg my_eyes = 'Brown' my_teeth = 'White' my_hair = 'Black'print "Let's talk about %s." % my_name print "He's %d centimeters tall." % my_height print "He's %d kilograms heavy." % my_weight print "Actually that's not too heavy." print "He's got %s eyes and %s hair." % (my_eyes, my_hair) print "His teeth are usually %s depending on the coffee." % my_teeth# this line is tricky, try to get it exactly right print "If I add %d, %d, and %d I get %d. I don't know what that means but, whatever." % ( my_age, my_height, my_weight, my_age + my_height + my_weight)

1)使用第三方库 为了轻松而轻松地执行python脚本, 你可以使用python-shell库实现你的目标。该模块是从Node.js运行Python脚本的简单方法, 它具有基本但高效的进程间通信和更好的错误处理能力。
要在你的项目中安装此模块, 请在节点命令提示符下执行以下命令:
npm install python-shell

Python shell在后台使用子进程来完成此任务。在此处阅读有关此模块API的更多信息, 或访问Github中的存储库。
var myPythonScriptPath = 'script.py'; // Use python shell var PythonShell = require('python-shell'); var pyshell = new PythonShell(myPythonScriptPath); pyshell.on('message', function (message) { // received a message sent from the Python script (a simple "print" statement) console.log(message); }); // end the input stream and allow the process to exit pyshell.end(function (err) { if (err){ throw err; }; console.log('finished'); });

在控制台中生成以下结果:
如何执行Python脚本并检索Node.js中的输出(数据和错误)

文章图片
请注意, 该脚本假定你已经可以从控制台获得Python作为环境变量。如果你不是这种情况, 请不用担心, Python Shell允许你在执行时设置一些基本选项(即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('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); });

使用参数执行python脚本
一些python脚本需要参数才能执行。 Python Shell允许你在运行脚本时使用options参数添加参数。
以下python脚本(script.py)应在执行时列出所有参数:
import sysprint "\n".join(sys.argv)

例如, 为了在Node.js中执行脚本, 可以通过以下方式直接在控制台中使用python执行脚本:
python script.py "my First Argument" "My Second Argument" --option=123

我们只需要在options对象的args键中提供一个数组作为值, 并带有相应的值:
var PythonShell = require('python-shell'); var options = { mode: 'text', args: ['my First Argument', 'My Second Argument', '--option=123'] }; PythonShell.run('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); });

就是这样! python shell模块使这项任务易于实现, 并且非常全面。
从Node.js向Python提供数据
要将数据从Javascript发送到我们的Python脚本, 我们需要在过程中使用标准输入(stdin)编写文本。
使用python shell, 你可以轻松地处理标准输入并使用send方法发送信息。在此示例中, 我们将发送一个数组(字符串格式), 稍后将使用python处理该数组:
var PythonShell = require('python-shell'); var pyshell = new PythonShell('script.py'); pyshell.send(JSON.stringify([1, 2, 3, 4, 5])); pyshell.on('message', function (message) { // received a message sent from the Python script (a simple "print" statement) console.log(message); }); // end the input stream and allow the process to exit pyshell.end(function (err) { if (err){ throw err; }; console.log('finished'); });

【如何执行Python脚本并检索Node.js中的输出(数据和错误)】python脚本应该使用标准输入(stdin)在Javascript提供的数组中打印项目的总和:
import sys, json#Read data from stdin def read_in(): lines = sys.stdin.readlines() # Since our input would only be having one line, parse our JSON data from that return json.loads(lines[0])def main(): #get our data as an array from read_in() lines = read_in()# Sumof all the items in the providen array total_sum_inArray = 0 for item in lines: total_sum_inArray += item#return the sum to the output stream print total_sum_inArray# Start process if __name__ == '__main__': main()

Node.js控制台中的输出应为15。
2)使用内置的child_process模块 如果你不想依靠任何库来完成此任务, 则可以使用child_process生成python环境并自己在该环境上执行脚本。
child_process模块??提供了以类似于但不相同的方式生成子进程的能力。此功能主要由child_process.spawn函数提供:
// The path to your python script var myPythonScript = "script.py"; // Provide the path of the python executable, if python is available as environment variable then you can use only "python" var pythonExecutable = "python.exe"; // Function to convert an Uint8Array to a string var uint8arrayToString = function(data){ return String.fromCharCode.apply(null, data); }; const spawn = require('child_process').spawn; const scriptExecution = spawn(pythonExecutable, [myPythonScript]); // Handle normal output scriptExecution.stdout.on('data', (data) => { console.log(uint8arrayToString(data)); }); // Handle error output scriptExecution.stderr.on('data', (data) => { // As said before, convert the Uint8Array to a readable string. console.log(uint8arrayToString(data)); }); scriptExecution.on('exit', (code) => { console.log("Process quit with code : " + code); });

在上一个脚本中, 我们已经实现了python-shell模块必须提供的大多数功能。它需要child_process模块??, 然后我们使用spawn方法以python脚本的路径作为第一个参数来启动python, 并向stdout和stderr属性添加一些侦听器以处理输出。
使用参数执行python脚本
如果你专心, 那么你就会知道我们已经在spawn函数的脚本初始化中使用了参数。 python脚本的路径已经是一个参数, 因此, 如果要添加更多参数, 请随时向spawn函数的第二个参数数组添加更多值:
const scriptExecution = spawn(pythonExecutable, ["my_Script.py", "Argument 1", "Argument 2"]);

从Node.js向Python提供数据
要将数据从Javascript发送到我们的Python脚本, 我们需要在过程中使用标准输入(stdin)编写文本。
在此示例中, 我们将发送一个数组(使用JSON.stringify方法以字符串格式)到Python:
const spawn = require('child_process').spawn; const scriptExecution = spawn("python.exe", ["script.py"]); // Handle normal output scriptExecution.stdout.on('data', (data) => { console.log(String.fromCharCode.apply(null, data)); }); // Write data (remember to send only strings or numbers, otherwhise python wont understand) var data = http://www.srcmini.com/JSON.stringify([1, 2, 3, 4, 5]); scriptExecution.stdin.write(data); // End data write scriptExecution.stdin.end();

python脚本应该使用标准输入(stdin)在Javascript提供的数组中打印项目的总和:
import sys, json#Read data from stdin def read_in(): lines = sys.stdin.readlines() # Since our input would only be having one line, parse our JSON data from that return json.loads(lines[0])def main(): #get our data as an array from read_in() lines = read_in()# Sumof all the items in the providen array total_sum_inArray = 0 for item in lines: total_sum_inArray += item#return the sum to the output stream print total_sum_inArray# Start process if __name__ == '__main__': main()

Node.js控制台中的输出应为15。
玩得开心 !

    推荐阅读