本文概述
- 1)使用第三方库
- 2)使用内置的child_process模块
但另一方面, 你可能仍想使用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 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。
玩得开心 !
推荐阅读
- EmailChecker评论(最好的电子邮件验证工具之一)
- 每日三道面试题,通往自由的道路14——MySQL
- Ubuntu系统用ceph-deploy部署ceph
- RocketMQ基础概念剖析,并分析一下Producer的底层源码
- 超硬核学习手册系列1——深入浅出MySQL的知识点,学习收藏必备
- NameServer 核心原理解析
- 灵活运用分布式锁解决数据重复插入问题
- #导入MD文档图片#超硬核学习手册系列2查询篇——深入浅出MySQL的知识点,学习收藏必备
- 从RocketMQ的Broker源码层面验证一下这两个点