Как выполнить скрипт Python и получить выходные данные (данные и ошибки) в Node.js

Node.js использует управляемую событиями неблокирующую модель ввода-вывода, которая делает ее легкой и эффективной, идеально подходящей для приложений с интенсивным использованием данных в реальном времени, работающих на распределенных устройствах, однако существует несколько вычислительных задач, для которых вы бы предпочли Python если вы сильно обеспокоены скоростью вашего проекта.

Но, с другой стороны, вы, возможно, захотите по-прежнему работать с Node.js, поэтому вам нужно научиться выполнять скрипт Python из Node. В этом случае мы рассмотрим самые основные моменты, касающиеся того, как выполнить скрипт 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-оболочки библиотека для достижения вашей цели. Этот модуль представляет собой простой способ запуска скриптов Python из Node.js с базовым, но эффективным межпроцессным взаимодействием и лучшей обработкой ошибок.

Чтобы установить этот модуль в своем проекте, выполните следующую команду в командной строке вашего узла:

npm install python-shell

Оболочка Python использует дочерний процесс для выполнения этой задачи. Прочитайте больше об 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 позволяет вам установить некоторые основные параметры при выполнении (т. Е. Путь к исполняемому файлу 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 позволяет добавлять аргументы с помощью параметра 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

Нам нужно только предоставить массив как значение в ключе 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 делает эту задачу легкой и всеобъемлющей.

Предоставление данных из Node.js в Python

Чтобы отправить данные из Javascript в наш скрипт Python, нам нужно написать текст, используя стандартный ввод (stdin) в процессе.

С оболочкой python вы можете легко обрабатывать стандартный ввод и отправлять информацию, используя метод 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 должен печатать сумму элементов в массиве, предоставленном Javascript, используя стандартный ввод (stdin):

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 Модуль предоставляет возможность порождать дочерние процессы способом, подобным, но не идентичным, для popen. Эта возможность в первую очередь обеспечивается 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 должен печатать сумму элементов в массиве, предоставленном Javascript, используя стандартный ввод (stdin):

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.

Повеселись !

Ссылка на основную публикацию
Adblock
detector