#javascript #python-3.x #spawn #spawning
#javascript #python-3.x #порождение #порождение
Вопрос:
Я использую вывод скрипта Python в своем node.js приложение.
Однако мне нужно запросить его в другой раз (и, возможно, несколько раз).
Я не могу этого сделать, потому что процесс Python завершается и не может быть перезапущен. Я попытался переназначить переменную, но это не сработало. Как снова запустить скрипт Python? Вот мой код:
var spawn = require('child_process').spawn,
interval_data = [1,2,4,5,6,7],
interval_dataString = '';
var py = undefined
startPython()
py.stdout.on('data', function(data){
interval_dataString = data.toString();
console.log(interval_dataString)
});
py.stdout.on('end', function(){
console.log('Alpha Component =',interval_dataString);
setTimeout(() => {
startPython()
},1000)
});
function startPython() {
py = undefined
py = spawn('python', ['dfa.py'])
py.stdin.write(JSON.stringify(interval_data));
py.stdin.end();
}
Вот код Python:
## compute_input.py
import sys, json, numpy as np
#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])
#lines = "[1,2]" # for testing
#return json.loads(lines) # for testing
def main():
#get our data as an array from read_in()
lines = read_in()
#create a numpy array
np_lines = np.array(lines)
#use numpys sum method to find sum of all elements in the array
lines_sum = np.sum(np_lines)
#return the sum to the output stream
print(lines_sum)
#start process
if __name__ == '__main__':
main()
Комментарии:
1. Можете ли вы опубликовать свой код на Python? Итак, я могу протестировать свой пример
2. Привет, @Marc добавил мой код на python!
Ответ №1:
Вы переопределяете дочерний процесс. Таким образом, вы больше не можете использовать исходный объект (источник события).
Это проще, чем вы думали, может быть 🙂
Просто вызовите / переместите элемент источника событий внутри функции «пуск». Итак, каждый раз, когда вы создаете дочерний объект, вы используете новый дочерний объект / источник событий.
const { spawn } = require("child_process");
const interval_data = [1, 2, 4, 5, 6, 7]
const interval_response = [];
// use this as exit strategie
var should_restart = true;
function start() {
// spawn python child
let child = spawn("python3", ["dfa.py"]);
// would be better to work on buffer objects
// create on final child/python exit a string out of the buffer
child.stdout.on("data", (data) => {
interval_response.push(data.toString());
});
// listen for the close event
child.on("close", () => {
if (should_restart) {
// feedback
console.log("Alpha Component =", interval_response.join());
setTimeout(() => {
start();
}, 1000)
} else {
// nope, not now!
console.log("DIE!", interval_response);
// Do what ever you want with the result here
}
});
// write stuff to python child process
child.stdin.write(JSON.stringify(interval_data));
}
start();
// let the programm run for min. 5sec
setTimeout(() => {
should_restart = false;
}, 5000);
Протестировано с вашим кодом на python.
node index.js
Alpha Component = 3
Alpha Component = 3
,3
Alpha Component = 3
,3
,3
Alpha Component = 3
,3
,3
,3
DIE! [ '3n', '3n', '3n', '3n', '3n' ]
Я думал, вы на самом деле читаете в своем скрипте python из stdin. (И не только фиктивная функция)
Но для части узла это не должно иметь никакого значения.
Протестировано на Ubuntu 18.04 x64, node: v13.14.0, python: 3.6.9.
Редактировать:
Создан на основе вашего фрагмента python, скрипта, который считывает из стандартного набора и создает сумму из всех переданных чисел:
import sys, json
def main():
data = sys.stdin.read()
data = json.loads(data)
#print("debug:", data)
chunks_sum = sum(data)
#print("debug", chunks_sum)
sys.stdout.write(str(chunks_sum))
#start process
if __name__ == '__main__':
main()
Измененная функция запуска:
function start() {
// spawn python child
let child = spawn("python3", ["dfa.py"]);
// would be better to work on buffer objects
// create on final child/python exit a string out of the buffer
child.stdout.on("data", (data) => {
// since your python code just create
// a sum of all numbers, store the
// returend stuff as number
interval_response.push(Number(data));
});
// listen for the close event
child.on("close", () => {
if (should_restart) {
// feedback
console.log("Alpha Component =", interval_response);
setTimeout(() => {
start();
}, 1000)
} else {
// nope, not now!
console.log("DIE!", interval_response);
// create sum of all sum chunks from python
// not sure what you want to do with the "interval_response" array
// just for demo purpose
let sum = interval_response.reduce((pv, cv) => pv cv, 0);
console.log("Total sum", sum);
}
});
// write stuff to python child process
//child.stdin.write();
child.stdin.end(JSON.stringify(interval_data));
}
Изменено child.stdin.write
на child.stdin.end
, так что теперь python может «запуститься», и dosnt должен ждать дополнительных данных.
Примечание: я не знаю, как работает «буферизация» IPC / stdio. Возможно, вы сталкиваетесь с некоторыми подозрительными вещами, если работаете с большими данными.
Более того, мы сохраняем данные из python, которые записываются в «стандартный вывод», как число в массиве interval_response
, поскольку вы просто вычисляете общую сумму данных, которые мы записываем в «стандартный вывод».
Комментарии:
1. Спасибо за ответ, но на самом деле, если мы читаем ввод JS в python, скрипт не работает. Я изменил приведенный выше скрипт python, пожалуйста, проверьте, по какой-то причине он не работает с этой модификацией… Вы знаете, почему? Если я добавлю
py.stdin.end();
, это сработает, но только один раз.