本文概述
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作为环境变量。如果你不是这种情况, 请不用担心, 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 sys
print "\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脚本应该使用标准输入(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()
# Sum of 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 = 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()
# Sum of 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。
玩得开心 !
评论前必须登录!
注册